test: fix mock configuration and lint errors in unit tests

- Fix logger mock missing default export in extractor.test.ts
- Fix performance-monitor mock configuration
- Fix prefer-const in validation-database.test.ts
- Fix no-unsafe-function-type in cleaner-handler.test.ts
- Fix no-empty-function in cleaner-application-service.test.ts
- Run prettier format on test files

All 622 tests now passing (59 files, 3 skipped)
This commit is contained in:
Misaka
2026-04-05 22:04:32 +08:00
parent c6f67e49a4
commit fb3bdbc493
5 changed files with 57 additions and 25 deletions

View File

@@ -305,6 +305,7 @@
```
3. **错误处理验证**
```typescript
it('should handle errors in batch download gracefully', async () => {
vi.spyOn(extractorCore as any, 'downloadBatch')

View File

@@ -18,7 +18,7 @@ vi.mock('../../../src/main/services/logger/error-utils', () => ({
}))
// In-memory storage for registered IPC handlers
const registeredHandlers: Map<string, Function> = new Map()
const registeredHandlers: Map<string, (...args: any[]) => any> = new Map()
// Mock Electron's ipcMain to capture registered handlers
vi.mock('electron', () => {

View File

@@ -23,7 +23,7 @@ vi.mock('../../../../src/main/services/config/config-manager', () => {
vi.mock('../../../../src/main/services/erp/order-resolver', () => {
return {
OrderNumberResolver: class {
constructor(_dbService: any) {}
constructor(_dbService: any) {} // eslint-disable-line @typescript-eslint/no-empty-function
async resolve(orderNumbers: string[]) {
return orderNumbers
}
@@ -71,7 +71,7 @@ let erpAuthCloseCalled = false
vi.mock('../../../../src/main/services/erp/erp-auth', () => {
return {
ErpAuthService: class {
constructor(_config: any) {}
constructor(_config: any) {} // eslint-disable-line @typescript-eslint/no-empty-function
async login() {
return Promise.resolve(undefined)
}
@@ -157,10 +157,16 @@ describe('CleanerApplicationService', () => {
it('should increase materialsDeleted when dryRun is false vs true', async () => {
const eventSender: any = { send: vi.fn() }
const resDry = await service.runCleaner(eventSender, makeInput({ dryRun: true, orderNumbers: ['SC1', 'SC2', 'SC3'] }))
const resDry = await service.runCleaner(
eventSender,
makeInput({ dryRun: true, orderNumbers: ['SC1', 'SC2', 'SC3'] })
)
expect(resDry.materialsDeleted).toBe(0)
const resActual = await service.runCleaner(eventSender, makeInput({ dryRun: false, orderNumbers: ['SC1', 'SC2', 'SC3'] }))
const resActual = await service.runCleaner(
eventSender,
makeInput({ dryRun: false, orderNumbers: ['SC1', 'SC2', 'SC3'] })
)
expect(resActual.materialsDeleted).toBe(3)
expect(lastCleanerInput?.dryRun).toBe(false)
})
@@ -168,7 +174,10 @@ describe('CleanerApplicationService', () => {
it('should handle different order counts independently across invocations', async () => {
const eventSender: any = { send: vi.fn() }
const res1 = await service.runCleaner(eventSender, makeInput({ orderNumbers: ['SC1', 'SC2'] }))
const res1 = await service.runCleaner(
eventSender,
makeInput({ orderNumbers: ['SC1', 'SC2'] })
)
expect(res1.ordersProcessed).toBe(2)
const res2 = await service.runCleaner(eventSender, makeInput({ orderNumbers: ['SC3'] }))
@@ -178,9 +187,9 @@ describe('CleanerApplicationService', () => {
it('should reject when ERP config fetch fails', async () => {
;(service as any).getErpConfig = vi.fn().mockRejectedValue(new Error('ERP config error'))
await expect(
service.runCleaner({ send: vi.fn() } as any, makeInput())
).rejects.toThrow('ERP config error')
await expect(service.runCleaner({ send: vi.fn() } as any, makeInput())).rejects.toThrow(
'ERP config error'
)
})
it('should reject with DatabaseQueryError when database connection fails', async () => {
@@ -218,10 +227,13 @@ describe('CleanerApplicationService', () => {
it('should handle processConcurrency=0 gracefully', async () => {
const eventSender: any = { send: vi.fn() }
const result = await service.runCleaner(eventSender, makeInput({
orderNumbers: ['SC1'],
processConcurrency: 0
}))
const result = await service.runCleaner(
eventSender,
makeInput({
orderNumbers: ['SC1'],
processConcurrency: 0
})
)
expect(result.ordersProcessed).toBe(1)
})
@@ -236,9 +248,9 @@ describe('CleanerApplicationService', () => {
cleanerShouldThrow = true
cleanerError = new Error('cleaner crashed')
await expect(
service.runCleaner({ send: vi.fn() } as any, makeInput())
).rejects.toThrow('cleaner crashed')
await expect(service.runCleaner({ send: vi.fn() } as any, makeInput())).rejects.toThrow(
'cleaner crashed'
)
expect(erpAuthCloseCalled).toBe(true)
})
@@ -271,9 +283,9 @@ describe('CleanerApplicationService', () => {
cleanerShouldThrow = true
cleanerError = new Error('boom')
await expect(
service.runCleaner({ send: vi.fn() } as any, makeInput())
).rejects.toThrow('boom')
await expect(service.runCleaner({ send: vi.fn() } as any, makeInput())).rejects.toThrow(
'boom'
)
expect(mockDisconnect).toHaveBeenCalled()
})
@@ -282,8 +294,24 @@ describe('CleanerApplicationService', () => {
describe('exportResults', () => {
it('should export results successfully for non-empty items', async () => {
const items = [
{ materialCode: 'M1', materialName: 'Mat A', specification: '', model: '', managerName: 'Mgr', isMarkedForDeletion: false, isSelected: true },
{ materialCode: 'M2', materialName: 'Mat B', specification: '', model: '', managerName: 'Mgr', isMarkedForDeletion: true, isSelected: false }
{
materialCode: 'M1',
materialName: 'Mat A',
specification: '',
model: '',
managerName: 'Mgr',
isMarkedForDeletion: false,
isSelected: true
},
{
materialCode: 'M2',
materialName: 'Mat B',
specification: '',
model: '',
managerName: 'Mgr',
isMarkedForDeletion: true,
isSelected: false
}
]
const result = await service.exportResults(items as any)

View File

@@ -25,15 +25,18 @@ vi.mock('../../../../src/main/services/logger', () => {
}
return {
default: mockLogger,
createLogger: vi.fn(() => mockLogger),
withRequestContext: vi.fn(async (fn) => fn()),
getRequestId: vi.fn(() => 'test-request-id')
}
})
vi.mock('../../../../src/main/services/logger/performance-monitor', () => ({
trackDuration: vi.fn(async (fn) => ({ result: await fn() }))
}))
vi.mock('../../../../src/main/services/logger/performance-monitor', () => {
return {
trackDuration: vi.fn(async (fn) => ({ result: await fn() }))
}
})
// Mock ExcelParser - reset in beforeEach
let mockExcelParserInstance: any

View File

@@ -9,7 +9,7 @@ let lastPgOpts: any = null
let pgConnectCalled = false
let currentDbType: string = 'mysql'
let currentDbConfig: any = {
const currentDbConfig: any = {
database: {
mysql: { host: 'db', port: 3306, username: 'user', password: 'pass', database: 'erp' },
sqlserver: {