From fb3bdbc49354dd1e856f124de7db4b648015eeed Mon Sep 17 00:00:00 2001 From: Misaka Date: Sun, 5 Apr 2026 22:04:32 +0800 Subject: [PATCH] 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) --- docs/TEST_QUALITY_REVIEW_REPORT.md | 1 + tests/unit/ipc/cleaner-handler.test.ts | 2 +- .../cleaner-application-service.test.ts | 68 +++++++++++++------ tests/unit/services/erp/extractor.test.ts | 9 ++- .../validation/validation-database.test.ts | 2 +- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/docs/TEST_QUALITY_REVIEW_REPORT.md b/docs/TEST_QUALITY_REVIEW_REPORT.md index e761d3c..c5594af 100644 --- a/docs/TEST_QUALITY_REVIEW_REPORT.md +++ b/docs/TEST_QUALITY_REVIEW_REPORT.md @@ -305,6 +305,7 @@ ``` 3. **错误处理验证** + ```typescript it('should handle errors in batch download gracefully', async () => { vi.spyOn(extractorCore as any, 'downloadBatch') diff --git a/tests/unit/ipc/cleaner-handler.test.ts b/tests/unit/ipc/cleaner-handler.test.ts index af24b23..e3efca1 100644 --- a/tests/unit/ipc/cleaner-handler.test.ts +++ b/tests/unit/ipc/cleaner-handler.test.ts @@ -18,7 +18,7 @@ vi.mock('../../../src/main/services/logger/error-utils', () => ({ })) // In-memory storage for registered IPC handlers -const registeredHandlers: Map = new Map() +const registeredHandlers: Map any> = new Map() // Mock Electron's ipcMain to capture registered handlers vi.mock('electron', () => { diff --git a/tests/unit/services/cleaner/cleaner-application-service.test.ts b/tests/unit/services/cleaner/cleaner-application-service.test.ts index 613ee23..75d28a5 100644 --- a/tests/unit/services/cleaner/cleaner-application-service.test.ts +++ b/tests/unit/services/cleaner/cleaner-application-service.test.ts @@ -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) diff --git a/tests/unit/services/erp/extractor.test.ts b/tests/unit/services/erp/extractor.test.ts index 375966c..4b9e5df 100644 --- a/tests/unit/services/erp/extractor.test.ts +++ b/tests/unit/services/erp/extractor.test.ts @@ -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 diff --git a/tests/unit/services/validation/validation-database.test.ts b/tests/unit/services/validation/validation-database.test.ts index 52cc507..b8abd46 100644 --- a/tests/unit/services/validation/validation-database.test.ts +++ b/tests/unit/services/validation/validation-database.test.ts @@ -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: {