week-7: fix unit tests with pg mock for PostgreSQL integration

This commit is contained in:
ikechukwu Elizabeth
2026-05-21 03:37:19 +01:00
parent 6ddd7cba1f
commit 958a4d5e1c
+65 -1
View File
@@ -1,6 +1,31 @@
const request = require('supertest'); const request = require('supertest');
// Mock the pg Pool before importing app so no real
// database connection is attempted during tests
jest.mock('pg', () => {
const mPool = {
query: jest.fn(),
};
return { Pool: jest.fn(() => mPool) };
});
// Mock initDb so the server does not try to create
// the tasks table on startup during tests
jest.mock('./db', () => ({
pool: {
query: jest.fn(),
},
initDb: jest.fn().mockResolvedValue(),
}));
const { pool } = require('./db');
const app = require('./server'); const app = require('./server');
// Reset all mocks between tests so they don't bleed into each other
beforeEach(() => {
jest.clearAllMocks();
});
describe('Health Check', () => { describe('Health Check', () => {
it('GET /api/health returns 200 with status ok', async () => { it('GET /api/health returns 200 with status ok', async () => {
const res = await request(app).get('/api/health'); const res = await request(app).get('/api/health');
@@ -11,12 +36,19 @@ describe('Health Check', () => {
describe('Tasks API', () => { describe('Tasks API', () => {
it('GET /api/tasks returns empty array initially', async () => { it('GET /api/tasks returns empty array initially', async () => {
pool.query.mockResolvedValueOnce({ rows: [] });
const res = await request(app).get('/api/tasks'); const res = await request(app).get('/api/tasks');
expect(res.statusCode).toBe(200); expect(res.statusCode).toBe(200);
expect(Array.isArray(res.body)).toBe(true); expect(Array.isArray(res.body)).toBe(true);
expect(res.body).toHaveLength(0);
}); });
it('POST /api/tasks creates a new task', async () => { it('POST /api/tasks creates a new task', async () => {
pool.query.mockResolvedValueOnce({
rows: [{ id: 1, title: 'Test task', completed: false, created_at: new Date() }],
});
const res = await request(app) const res = await request(app)
.post('/api/tasks') .post('/api/tasks')
.send({ title: 'Test task' }); .send({ title: 'Test task' });
@@ -31,4 +63,36 @@ describe('Tasks API', () => {
.send({}); .send({});
expect(res.statusCode).toBe(400); expect(res.statusCode).toBe(400);
}); });
});
it('PATCH /api/tasks/:id toggles completed status', async () => {
pool.query.mockResolvedValueOnce({
rowCount: 1,
rows: [{ id: 1, title: 'Test task', completed: true, created_at: new Date() }],
});
const res = await request(app).patch('/api/tasks/1');
expect(res.statusCode).toBe(200);
expect(res.body.completed).toBe(true);
});
it('PATCH /api/tasks/:id returns 404 when task not found', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 0, rows: [] });
const res = await request(app).patch('/api/tasks/999');
expect(res.statusCode).toBe(404);
});
it('DELETE /api/tasks/:id deletes a task', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 1 });
const res = await request(app).delete('/api/tasks/1');
expect(res.statusCode).toBe(204);
});
it('DELETE /api/tasks/:id returns 404 when task not found', async () => {
pool.query.mockResolvedValueOnce({ rowCount: 0 });
const res = await request(app).delete('/api/tasks/999');
expect(res.statusCode).toBe(404);
});
});