Заглушка Sinon для узла - postgres клиент - PullRequest
0 голосов
/ 11 февраля 2020

Я пишу Node-приложение на TypeScript, которое запрашивает базу данных Postgres. В модульных тестах я не могу смоделировать функцию запроса.

Мой код модуля выглядит следующим образом:

class MyClass {

  /* more stuff */

  async validate(event: any): Promise<boolean> {
    const client = new Client();
    await client.connect();

    const result = await client.query(`SELECT * FROM "user" WHERE "user_id" = '${user_id}'`);

    console.log(
      result
    );

    /* more logic */
  }
}

Мой модульный тест выглядит следующим образом:

describe("...", () => {
  sinon.stub(pg.Client.prototype, "connect").resolves();
  let stub = sinon.stub(pg.Client.prototype, "query").withArgs(
    `SELECT * FROM "user" WHERE "user_id" = '1234'`,
     sinon.match.any,
     sinon.match.any
  ).resolves("asdf");

  it("...", () => {
    await myClassInstance.validate(event);
  });
});

Не говоря уже о тестовых ожиданиях, я бы сказал, что на консоли напечатано «asdf». Но я не знаю!

Я попытался полностью удалить .withArgs(...), и тогда я вижу «asdf». (Но, очевидно, это не очень помогает ...)

Я также пытался напечатать stub.lastCall, и я вижу

args: [ `SELECT * FROM "user" WHERE "user_id" = 'user_with_verified_subscription'` ]

где-то тогда ...

Удаление двух sinon.match.any сопоставителей также не помогает, потому что тогда компилятор TS жалуется, что Client.query принимает 3 аргумента ...

Любая помощь очень ценится!

С уважением,

Макс

1 Ответ

0 голосов
/ 12 февраля 2020

Вот решение для модульного тестирования с использованием proxyquire и sinon:

index.ts:

import { Client } from 'pg';

class MyClass {
  async validate(event: any) {
    const user_id = 1;
    const client = new Client();
    await client.connect();

    const result = await client.query(`SELECT * FROM "user" WHERE "user_id" = '${user_id}'`);

    console.log(result);
  }
}

export default MyClass;

index.test.ts:

import sinon from 'sinon';
import proxyquire from 'proxyquire';

describe('60172091', () => {
  it('should valdiate', async () => {
    const pgClientStub = {
      connect: sinon.stub().returnsThis(),
      query: sinon
        .stub()
        .withArgs(`SELECT * FROM "user" WHERE "user_id" = '1'`)
        .resolves('asdf'),
    };
    const pgStub = sinon.stub().callsFake(() => pgClientStub);
    const MyClass = proxyquire('./index', {
      pg: { Client: pgStub },
    }).default;
    const logSpy = sinon.spy(console, 'log');
    const instance = new MyClass();
    await instance.validate();
    sinon.assert.calledOnce(pgStub);
    sinon.assert.calledOnce(pgClientStub.connect);
    sinon.assert.calledWithExactly(pgClientStub.query, `SELECT * FROM "user" WHERE "user_id" = '1'`);
    sinon.assert.calledWithExactly(logSpy, 'asdf');
  });
});

Результаты модульного тестирования со 100% покрытием:

60172091
asdf
    ✓ should valdiate (2212ms)


  1 passing (2s)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
...