// tests/main/services/DictionaryService.test.ts // DictionaryService 단위 테스트 — DB 모킹 import { describe, it, expect, beforeEach, vi } from 'vitest' function createMockQueryBuilder(data: unknown[] = []) { const builder: Record = {} builder.values = vi.fn(() => ({ run: vi.fn(() => ({ changes: 1 })) })) builder.from = vi.fn(() => builder) builder.where = vi.fn(() => builder) builder.orderBy = vi.fn(() => builder) builder.limit = vi.fn(() => builder) builder.offset = vi.fn(() => builder) builder.set = vi.fn(() => builder) builder.get = vi.fn(() => data[0] ?? null) builder.all = vi.fn(() => data) builder.run = vi.fn(() => ({ changes: 1 })) return builder } const mockDb = { insert: vi.fn(() => createMockQueryBuilder()), select: vi.fn(() => createMockQueryBuilder()), update: vi.fn(() => createMockQueryBuilder()), delete: vi.fn(() => createMockQueryBuilder()) } vi.mock('../../../src/main/db', () => ({ getDatabase: () => mockDb })) vi.mock('../../../src/main/services/LoggerService', () => ({ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }) })) let getDictionaryService: () => ReturnType beforeEach(async () => { vi.resetModules() vi.clearAllMocks() const mod = await import('../../../src/main/services/DictionaryService') getDictionaryService = mod.getDictionaryService }) describe('DictionaryService', () => { describe('add', () => { it('insert를 호출하고 엔트리를 반환한다', () => { const svc = getDictionaryService() const entry = svc.add({ word: 'AI', pronunciation: '에이아이', category: 'technical' }) expect(mockDb.insert).toHaveBeenCalled() expect(entry.id).toBeDefined() expect(entry.word).toBe('AI') expect(entry.pronunciation).toBe('에이아이') expect(entry.category).toBe('technical') expect(entry.usageCount).toBe(0) }) it('기본 카테고리는 user이다', () => { const svc = getDictionaryService() const entry = svc.add({ word: '테스트' }) expect(entry.category).toBe('user') }) it('pronunciation 미지정 시 null이다', () => { const svc = getDictionaryService() const entry = svc.add({ word: 'test' }) expect(entry.pronunciation).toBeNull() }) }) describe('update', () => { it('없는 ID에 대해 null을 반환한다', () => { // select().from().where().get()이 null 반환 const svc = getDictionaryService() expect(svc.update({ id: 'nonexistent', word: 'test' })).toBeNull() }) }) describe('delete', () => { it('delete 쿼리를 실행하고 changes > 0이면 true를 반환한다', () => { const svc = getDictionaryService() expect(svc.delete('some-id')).toBe(true) expect(mockDb.delete).toHaveBeenCalled() }) }) describe('incrementUsage', () => { it('update 쿼리를 실행한다', () => { const svc = getDictionaryService() svc.incrementUsage('some-id') expect(mockDb.update).toHaveBeenCalled() }) }) describe('getPromptHints', () => { it('빈 목록에서 빈 문자열을 반환한다', () => { const svc = getDictionaryService() expect(svc.getPromptHints()).toBe('') }) }) describe('dispose', () => { it('에러 없이 호출된다', () => { const svc = getDictionaryService() expect(() => svc.dispose()).not.toThrow() }) }) })