test: add Vitest config and test utils

Made-with: Cursor
This commit is contained in:
Anton
2026-03-04 14:55:33 +03:00
parent 91b33f6f41
commit 85a3d274e6
4 changed files with 106 additions and 0 deletions

5
tests/setup.ts Normal file
View File

@@ -0,0 +1,5 @@
import { beforeAll, vi } from 'vitest';
beforeAll(() => {
vi.stubEnv('NODE_ENV', 'test');
});

12
tests/smoke.test.ts Normal file
View File

@@ -0,0 +1,12 @@
import { describe, it, expect } from 'vitest';
import { createMockDb } from './test-utils.js';
describe('test-utils', () => {
it('createMockDb returns mock with select, insert, update, delete', () => {
const db = createMockDb();
expect(db.select).toBeDefined();
expect(db.insert).toBeDefined();
expect(db.update).toBeDefined();
expect(db.delete).toBeDefined();
});
});

61
tests/test-utils.ts Normal file
View File

@@ -0,0 +1,61 @@
import { vi } from 'vitest';
import type { FastifyInstance } from 'fastify';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import type * as schema from '../src/db/schema/index.js';
export type MockDb = {
select: ReturnType<NodePgDatabase<typeof schema>['select']>;
insert: ReturnType<NodePgDatabase<typeof schema>['insert']>;
update: ReturnType<NodePgDatabase<typeof schema>['update']>;
delete: ReturnType<NodePgDatabase<typeof schema>['delete']>;
};
/**
* Create a chainable mock for Drizzle DB operations.
* Configure chain terminals (limit, returning) to resolve to desired values.
* Example: mockDb.select.mockReturnValue({ from: vi.fn().mockReturnValue({ where: vi.fn().mockReturnValue({ limit: vi.fn().mockResolvedValue([user]) }) }) })
*/
export function createMockDb(): MockDb {
const chain = {
from: vi.fn().mockReturnThis(),
where: vi.fn().mockReturnThis(),
values: vi.fn().mockReturnThis(),
set: vi.fn().mockReturnThis(),
orderBy: vi.fn().mockReturnThis(),
limit: vi.fn().mockReturnThis(),
returning: vi.fn().mockReturnThis(),
};
return {
select: vi.fn().mockReturnValue(chain),
insert: vi.fn().mockReturnValue(chain),
update: vi.fn().mockReturnValue(chain),
delete: vi.fn().mockReturnValue(chain),
} as unknown as MockDb;
}
/**
* Create a minimal mock Fastify app with db for route/integration tests.
* Use buildApp() from app.ts for full integration tests.
*/
export function createMockApp(): FastifyInstance & { db: MockDb } {
return {
db: createMockDb(),
log: {
child: () => ({
debug: () => {},
info: () => {},
warn: () => {},
error: () => {},
trace: () => {},
fatal: () => {},
}),
debug: () => {},
info: () => {},
warn: () => {},
error: () => {},
trace: () => {},
fatal: () => {},
},
} as FastifyInstance & { db: MockDb };
}

28
vitest.config.ts Normal file
View File

@@ -0,0 +1,28 @@
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['tests/**/*.test.ts', 'tests/**/*.spec.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'lcov'],
include: ['src/services/**/*.ts'],
exclude: [
'src/services/**/*.d.ts',
'**/*.test.ts',
'**/*.spec.ts',
'**/index.ts',
],
},
setupFiles: ['tests/setup.ts'],
testTimeout: 10000,
},
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
},
});