I am new in node.js. I am writing code in node.js for postgresql using pg
and pg-native
for serverless app. I need to write unit test for it. I am unable to mock pg
client using jest or sinon.
My actual code is like this
const { Client } = require('pg');
export const getAlerts = async (event, context) => {
const client = new Client({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: process.env.PORT
});
await client.connect();
try {
const result = await client.query(`SELECT * FROM public.alerts;`);
console.log(result.rows);
client.end();
return success({ message: `${result.rowCount} item(s) returned`, data: result.rows, status: true });
} catch (e) {
console.error(e.stack);
client.end();
return failure({ message: e, status: false });
}
};
How to mock pg
client here?
Here is the unit test solution using jestjs
:
index.js
:
const { Client } = require('pg');
const { success, failure } = require('./handler');
export const getAlerts = async (event, context) => {
const client = new Client({
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_DATABASE,
password: process.env.DB_PASSWORD,
port: process.env.PORT,
});
await client.connect();
try {
const result = await client.query(`SELECT * FROM public.alerts;`);
console.log(result.rows);
client.end();
return success({ message: `${result.rowCount} item(s) returned`, data: result.rows, status: true });
} catch (e) {
console.error(e.stack);
client.end();
return failure({ message: e, status: false });
}
};
hander.js
:
export function success(data) {}
export function failure(data) {}
index.spec.js
:
import { getAlerts } from './';
import { Client } from 'pg';
import { success, failure } from './handler';
jest.mock('pg', () => {
const mClient = {
connect: jest.fn(),
query: jest.fn(),
end: jest.fn(),
};
return { Client: jest.fn(() => mClient) };
});
jest.mock('./handler.js', () => {
return {
success: jest.fn(),
failure: jest.fn(),
};
});
describe('59540432', () => {
let client;
beforeEach(() => {
client = new Client();
});
afterEach(() => {
jest.clearAllMocks();
});
it('should success', async () => {
client.query.mockResolvedValueOnce({ rows: [], rowCount: 0 });
await getAlerts();
expect(client.connect).toBeCalledTimes(1);
expect(client.query).toBeCalledWith('SELECT * FROM public.alerts;');
expect(client.end).toBeCalledTimes(1);
expect(success).toBeCalledWith({ message: '0 item(s) returned', data: [], status: true });
});
it('should failure', async () => {
const mError = new Error('dead lock');
client.query.mockRejectedValueOnce(mError);
await getAlerts();
expect(client.connect).toBeCalledTimes(1);
expect(client.query).toBeCalledWith('SELECT * FROM public.alerts;');
expect(client.end).toBeCalledTimes(1);
expect(failure).toBeCalledWith({ message: mError, status: false });
});
});
Unit test result with 100% coverage:
PASS src/stackoverflow/59540432/index.spec.js (11.792s)
59540432
✓ should success (16ms)
✓ should failure (5ms)
console.log src/stackoverflow/59540432/index.js:3131
[]
console.error src/stackoverflow/59540432/index.js:3155
Error: dead lock
at /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:39:20
at step (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:33:23)
at Object.next (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:14:53)
at /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:8:71
at new Promise (<anonymous>)
at Object.<anonymous>.__awaiter (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:4:12)
at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59540432/index.spec.js:38:24)
at Object.asyncJestTest (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
at resolve (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>)
at mapper (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
at promise.then (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
at process._tickCallback (internal/process/next_tick.js:68:7)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 14.109s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59540432
Its an old question, but here is a new answer:
You can have a look at pg-mem, a library I released recently which emulates an in-memory postgres instance.
It supports most of the usual SQL queries (but will fail on less frequent syntaxes - file an issue if you encounter such a situation).
I wrote an article about it here
For your use case (how to use it with pg
), see the this wiki section
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With