如何使用 Sinon 在 GraphQL 解析器中模拟数据库对象?

How to mock a database object in GraphQL resolver using Sinon?

我希望能够对我的 apollo 解析器进行单元测试。我正在构建的应用程序是一个多租户应用程序,它在 运行 时间连接到特定数据库,即数据库在构建时未知。

解析器看起来像这样

getTemplates: async (_, args, { db }) => {
  const result = await db.goalTemplate.findAll()
  return result.slice(0, args.first)
},

虽然这是最简单的解析器,但它会在从 apollo gateway(我使用的是 apollo 联合)接收的上下文参数中获取数据库连接对象。

我想模拟这个数据库对象,以便我可以使用 sinon.js 对这个解析器进行单元测试。对这些解析器进行单元测试是个好主意吗?如果是,我应该如何编写可以在其他类似但更复杂的解析器中复制的测试用例。

使用 sinon.stub()db.goalTemplate.findAll() 方法创建存根。

例如

resolver.ts:

export const resolvers = {
  getTemplates: async (_, args, { db }) => {
    const result = await db.goalTemplate.findAll();
    return result.slice(0, args.first);
  },
};

resolver.test.ts:

import { resolvers } from './resolver';
import sinon from 'sinon';
import { expect } from 'chai';

describe('65888128', () => {
  it('should pass', async () => {
    const mDb = {
      goalTemplate: {
        findAll: sinon.stub().resolves([1, 2, 3]),
      },
    };
    const actual = await resolvers.getTemplates({}, { first: 2 }, { db: mDb });
    expect(actual).to.be.eql([1, 2]);
    sinon.assert.calledOnce(mDb.goalTemplate.findAll);
  });
});

单元测试结果:

  65888128
    ✓ should pass


  1 passing (5ms)

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