web-dev-qa-db-fra.com

Comment se moquer de postgresql (pg) dans node.js en utilisant jest

Je suis nouveau dans node.js. J'écris du code dans node.js pour postgresql en utilisant pg et pg-native pour une application sans serveur. J'ai besoin d'écrire un test unitaire pour cela. Je ne peux pas me moquer du client pg en utilisant jest ou sinon.

Mon code actuel est comme ça

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 });
  }

};

Comment se moquer du client pg ici?

3
Bilal Shah

Voici la solution de test unitaire utilisant 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 });
  });
});

Résultat du test unitaire avec une couverture de 100%:

 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

Code source: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59540432

2
slideshowp2