首页 > 解决方案 > 用于 node-postgres 客户端的 Sinon 存根

问题描述

我正在用 TypeScript 编写一个 Node 应用程序,它正在查询 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 个参数......

非常感谢任何帮助!

此致,

最大限度

标签: node.jstypescriptsinonstubnode-postgres

解决方案


proxyquire这是使用and的单元测试解决方案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 |                   
----------|---------|----------|---------|---------|-------------------

推荐阅读