|
| 1 | +# Mock Database Utilities |
| 2 | + |
| 3 | +Mock database objects for testing. No real database needed. |
| 4 | + |
| 5 | +## TestableDb |
| 6 | + |
| 7 | +`TestableDb` is a minimal interface in `@codebuff/common/types/contracts/database`. Both the real `CodebuffPgDatabase` and these mocks satisfy it, so you can pass mocks directly to functions without `as any`. |
| 8 | + |
| 9 | +## Utilities |
| 10 | + |
| 11 | +### `createMockDb(config?)` |
| 12 | + |
| 13 | +API route tests with insert/update/select: |
| 14 | + |
| 15 | +```ts |
| 16 | +import { createMockDb } from '@codebuff/common/testing/mock-db' |
| 17 | + |
| 18 | +const mockDb = createMockDb({ |
| 19 | + insert: { onValues: async (values) => { /* check values */ } }, |
| 20 | + update: { onWhere: async () => {} }, |
| 21 | + select: { results: [{ id: 'user-123' }] }, |
| 22 | +}) |
| 23 | + |
| 24 | +await postAgentRuns({ db: mockDb, ... }) |
| 25 | +``` |
| 26 | + |
| 27 | +### `createMockDbWithErrors(config)` |
| 28 | + |
| 29 | +Test error paths: |
| 30 | + |
| 31 | +```ts |
| 32 | +import { createMockDbWithErrors } from '@codebuff/common/testing/mock-db' |
| 33 | + |
| 34 | +const mockDb = createMockDbWithErrors({ |
| 35 | + insertError: new Error('Connection failed'), |
| 36 | + selectResults: [{ user_id: 'user-123' }], |
| 37 | +}) |
| 38 | +``` |
| 39 | + |
| 40 | +### `createSelectOnlyMockDb(results)` |
| 41 | + |
| 42 | +Read-only queries (version-utils, etc.): |
| 43 | + |
| 44 | +```ts |
| 45 | +import { createSelectOnlyMockDb } from '@codebuff/common/testing/mock-db' |
| 46 | + |
| 47 | +const mockDb = createSelectOnlyMockDb([{ major: 1, minor: 2, patch: 3 }]) |
| 48 | + |
| 49 | +const result = await getLatestAgentVersion({ |
| 50 | + agentId: 'test-agent', |
| 51 | + publisherId: 'test-publisher', |
| 52 | + db: mockDb, |
| 53 | +}) |
| 54 | +``` |
| 55 | + |
| 56 | +### `createMockDbSelect(config)` |
| 57 | + |
| 58 | +Batch queries (agent dependencies route): |
| 59 | + |
| 60 | +```ts |
| 61 | +import { createMockDbSelect, mockDbSchema } from '@codebuff/common/testing/mock-db' |
| 62 | + |
| 63 | +const mockDbSelect = mock(() => ({})) |
| 64 | +mock.module('@codebuff/internal/db', () => ({ default: { select: mockDbSelect } })) |
| 65 | + |
| 66 | +mockDbSelect.mockImplementation(createMockDbSelect({ |
| 67 | + publishers: [{ id: 'test-publisher' }], |
| 68 | + rootAgent: { id: 'agent', version: '1.0.0', publisher_id: 'test-publisher', data: {} }, |
| 69 | + childAgents: [], |
| 70 | +})) |
| 71 | +``` |
| 72 | + |
| 73 | +### `createMockLogger()` |
| 74 | + |
| 75 | +```ts |
| 76 | +import { createMockLogger } from '@codebuff/common/testing/mock-db' |
| 77 | + |
| 78 | +const mockLogger = createMockLogger() |
| 79 | +// error, warn, info, debug are all mocks |
| 80 | +``` |
| 81 | + |
| 82 | +## How to use |
| 83 | + |
| 84 | +1. Import from `@codebuff/common/testing/mock-db` |
| 85 | +2. Create in `beforeEach()` for fresh state |
| 86 | +3. Pass to functions that take `TestableDb` |
| 87 | + |
| 88 | +## Query patterns |
| 89 | + |
| 90 | +| Pattern | Use | |
| 91 | +|---------|---------| |
| 92 | +| `db.insert(table).values(data)` | `createMockDb` | |
| 93 | +| `db.update(table).set(data).where(cond)` | `createMockDb` | |
| 94 | +| `db.select().from().where().limit()` | `createMockDb` | |
| 95 | +| `db.select().from().where().orderBy().limit()` | `createSelectOnlyMockDb` | |
| 96 | +| Batch queries with counting | `createMockDbSelect` | |
0 commit comments