是否可以使用节点测试库Rewire模拟对同一函数的两次调用,以便它们返回不同的结果?

时间:2019-01-24 23:09:34

标签: node.js unit-testing express mocking

我不熟悉Node中的模拟。我正在使用Rewire库,这似乎是更好的选择之一。我遇到了一个问题,我需要在一个方法中模拟相同的函数两次,以便它们返回不同的结果:

const tourId: string = await redis.read(accessToken, false);
if (tourId === null) {
  logger.warn('invalid token', { accessToken });
  throw boom.notFound(codes.RECORD_NOT_FOUND);
}

logger.warn('found an access token', { tourId });

const tourResponse: string = await redis.read(tourId, false);
if (tourResponse === null) {
  logger.warn('tour not found', { accessToken, tourId });
  throw boom.notFound(codes.RECORD_NOT_FOUND);
}

在上面的示例中,我两次调用函数redis.read()。为了正确获得测试覆盖范围,我希望我需要用不同的方式模拟这两个我正在苦苦挣扎的电话。这是我到目前为止的测试用例:

it('returns a 404 error if access token not found in redis', async () => {
  service.__set__({
    redis: {
      read: (accessToken: string): string | null => null,
    },
  });

  service.getHandler('12345').catch((result: boom) => {
    expect(result.isBoom, 'should be boom error').to.be.true;
    expect(result.output.payload.statusCode, 'should be 404 error').to.equal(404);
    expect(result.output.payload.message, 'should be RECORD_NOT_FOUND error').to.equal(codes.RECORD_NOT_FOUND);
    });
});

任何提示都值得赞赏!

1 个答案:

答案 0 :(得分:0)

在这里回答我自己的问题:sinon.stub()有一个onCall()方法,可用于更改:nth调用的输出。

https://sinonjs.org/releases/latest/stubs/#stuboncalln-added-in-v18

it('returns an iTour instance if found in redis', async () => {
      const callback = sinon.stub();

      callback.onCall(0).returns('12345');
      callback.onCall(1).returns('67890');

      service.__set__({
        redis: {
          read: () => callback(),
        }
      });

      service.getHandler('12345').catch((result: boom) => {
        expect(result.isBoom, 'should be boom error').to.be.true;
        expect(result.output.payload.statusCode, 'should be 404 error').to.equal(404);
        expect(result.output.payload.message, 'should be RECORD_NOT_FOUND error').to.equal(codes.RECORD_NOT_FOUND);
      });
    });