Files
BIPMaterialManager/tests/unit/mocks/electron-ipc.test.ts
Misaka d45b65fa44 test: complete Wave 3 - Mock Library (6 tasks, 15+ Mock factories)
Wave 3: Mock Library Implementation
====================================

**Mock Factories (15+ total)**:
- Logger/ConfigManager (createMockLogger, createMockConfigManager)
- ErpAuthService (createMockErpAuthService with isLoggedIn/loginFails options)
- TypeORM/Database (createMockDataSource, createMockRepository, createMockDatabaseService)
- Electron/IPC (createMockElectron, createMockIpcRenderer)
- Utility modules (createMockFs, createMockPath, createMockExcelJS, createMockAxios, createMockChildProcess, createMockCrypto)

**Files Modified/Created**:
- tests/mocks/types.ts: +243 lines (Mock type definitions)
- tests/mocks/index.ts: +475 lines (Factory function implementations)
- docs/MOCK_LIBRARY_USAGE.md: 197 lines (Usage guide with 12+ examples)
- tests/unit/mocks/electron-ipc.test.ts: 12 tests (Electron/IPC Mock verification)

**Quality**:
- Zero any types
- All Mocks ≤20-30 lines
- Complete JSDoc documentation
- All factory functions support overrides customization

**Total Progress**:
- Wave 1: 4/4 
- Wave 2: 5/5 
- Wave 3: 6/6 
- Overall: 15/34 
2026-04-04 20:33:45 +08:00

151 lines
4.7 KiB
TypeScript

/**
* Tests for Electron and IPC Renderer mock factory functions
*
* These tests verify that the mock factory functions work correctly
* and can be used in unit tests for Electron/IPC functionality
*/
import { describe, it, expect, vi } from 'vitest'
import type { MockIpcRenderer, MockElectron } from '../../mocks/types'
import { createMockElectron, createMockIpcRenderer } from '../../mocks'
describe('Electron & IPC Mock Factories', () => {
describe('createMockIpcRenderer', () => {
it('should create IPC renderer with default mocks', () => {
const ipcRenderer = createMockIpcRenderer()
expect(ipcRenderer.invoke).toBeDefined()
expect(ipcRenderer.send).toBeDefined()
expect(ipcRenderer.on).toBeDefined()
expect(ipcRenderer.removeListener).toBeDefined()
})
it('should support invoke method with mocked response', async () => {
const mockResponse = { success: true, data: 'test' }
const ipcRenderer = createMockIpcRenderer({
invoke: vi.fn().mockResolvedValue(mockResponse)
})
const result = await ipcRenderer.invoke('test:channel', 'arg1')
expect(result).toEqual(mockResponse)
expect(ipcRenderer.invoke).toHaveBeenCalledWith('test:channel', 'arg1')
})
it('should support send method', () => {
const ipcRenderer = createMockIpcRenderer()
ipcRenderer.send('test:channel', 'data')
expect(ipcRenderer.send).toHaveBeenCalledWith('test:channel', 'data')
})
it('should support method chaining for on/removeListener', () => {
const ipcRenderer = createMockIpcRenderer()
const listener = () => {}
const result = ipcRenderer.on('channel', listener)
expect(result).toBe(ipcRenderer)
})
it('should accept overrides', async () => {
const customInvoke = vi.fn().mockResolvedValue({ custom: true })
const ipcRenderer = createMockIpcRenderer({
invoke: customInvoke
})
await ipcRenderer.invoke('test')
expect(customInvoke).toHaveBeenCalledWith('test')
})
})
describe('createMockElectron', () => {
it('should create Electron API with all modules', () => {
const electron = createMockElectron()
expect(electron.app).toBeDefined()
expect(electron.ipcMain).toBeDefined()
expect(electron.ipcRenderer).toBeDefined()
expect(electron.dialog).toBeDefined()
expect(electron.shell).toBeDefined()
expect(electron.BrowserWindow).toBeDefined()
})
it('should provide app module with getVersion', () => {
const electron = createMockElectron()
const version = electron.app?.getVersion()
expect(version).toBe('1.9.0-test')
})
it('should provide ipcRenderer with invoke support', async () => {
const electron = createMockElectron()
const result = await electron.ipcRenderer?.invoke('test:channel')
expect(electron.ipcRenderer?.invoke).toHaveBeenCalled()
})
it('should accept ipcRenderer overrides', async () => {
const mockResponse = { user: { id: 1, name: 'test' } }
const electron = createMockElectron({
ipcRenderer: createMockIpcRenderer({
invoke: vi.fn().mockResolvedValue(mockResponse)
})
})
const result = await electron.ipcRenderer?.invoke('user:getCurrent')
expect(result).toEqual(mockResponse)
})
it('should accept app module overrides', () => {
const electron = createMockElectron({
app: {
isPackaged: false,
isReady: vi.fn().mockReturnValue(true),
getPath: vi.fn(() => '/test'),
getVersion: vi.fn(() => '2.0.0-custom'),
getName: vi.fn(() => 'ERPAuto'),
getAppPath: vi.fn(() => '/test'),
on: vi.fn(),
off: vi.fn(),
once: vi.fn(),
emit: vi.fn(),
isDefaultProtocolClient: vi.fn(() => true),
quit: vi.fn(),
relaunch: vi.fn(),
exit: vi.fn(),
focus: vi.fn(),
blur: vi.fn(),
isQuitting: vi.fn(() => false),
isAccessibilityEnabled: vi.fn(() => true),
getApplicationNameForProtocol: vi.fn(() => null)
}
})
const version = electron.app?.getVersion()
expect(version).toBe('2.0.0-custom')
})
it('should support dialog mock', async () => {
const electron = createMockElectron()
await electron.dialog?.showMessageBox({})
expect(electron.dialog?.showMessageBox).toHaveBeenCalled()
})
it('should support shell mock', async () => {
const electron = createMockElectron()
await electron.shell?.openExternal('https://example.com')
expect(electron.shell?.openExternal).toHaveBeenCalledWith('https://example.com')
})
})
})