Sinon 存根返回错误的响应类型

Sinon stubs returning wrong response type

我的一个单元测试失败了。我认为这是因为存根 returning 错误的响应类型。或者也许我只是在测试错误的东西。这是我的方法

  let categories = Categories.create();
  let totalVideos = await Video.getTotalVideos();
  await categories.load();
  const data = categories.getData();
  if(data.length && totalVideos > 0) {
    let videoArray = [];
    for (let i = 0, categoryLength = data.length; i < categoryLength; i++) {
      let objId = data[i]._id;
      let results = await Search.findByCategoryId(objId.valueOf());
      ...
    }
    return utils.sendResponse(res, 200, utils.statusCodes.Success, {stats: videoArray});

这是我的测试:

describe('GET /v1/search/videos/categories', () => {
let stub, stubVideo, stubData;

beforeEach(() => {
  req = httpMocks.createRequest({
    url: '/v1/search/videos/categories',
    method: 'GET'
  });

  stub = sinon.stub(Categories.prototype, 'load');
  stubData = sinon.stub(Categories.prototype, 'getData');
  stubVideo = sinon.stub(Video, 'getTotalVideos');
});

afterEach(() => {
  stub.restore();
  stubData.restore();
  stubVideo.restore();
});

it('should return a 200 if success', async () => {
  stub.resolves([{"_id": new ObjectId()}]);
  stubData.resolves([{"_id": new ObjectId()}, {"_id": new ObjectId()}]);
  stubVideo.resolves(10);

  expect(stubVideo).to.be.above(0);
  expect(stubData).to.have.length.above(0);

  await searchController.getAllVideosByCategory(req, res);

  expect(res.statusCode).to.equal(200);
});

});

当测试运行时,getTotalVideos 的断言响应是 "AssertionError: expected getTotalVideos to be a number or a date"。获取类别数组的断言响应是 "AssertionError: expected [Function: proxy] to have a length above 0 but got 0".

要使整个测试正常进行,

videoCount > 0 && categories.length > 0

我如何让存根 return 正确的响应类型和值来完成这项工作?

我只添加了断言,因为 await searchController.getAllVideosByCategory(req, res) 保持 returning 404,这意味着由于某种原因,videosCount && categories.length 条件没有得到满足,这些断言告诉我没有 return 编辑必要的值来满足这些条件。因此,如果有另一种方法 return 这些值,以便方法 returns 200,请告诉我。

expect(stubVideo).to.be.above(0) 断言 stubVideo 是正数,而它是 returns 正数的函数。测试存根没有意义,它们是由您设置的。但可能有人断言他们被称为:

expect(stubVideo).to.have.been.calledOnce;
expect(stubVideo).to.have.been.calledWith();

测试应该在调用之前监视 utils.sendResponse 并断言它是用各自的参数调用的。

我一直在努力了解你想要实现的目标。

我在代码中发现了一些需要改进的地方:

  1. categories.getData() 源文件中添加 await
  2. 使用sandbox简化存根代码
  3. Search.findByCategoryId
  4. 添加 resolves
  5. 无需检查 to.be.above 等,因为您已经用预期值对其进行了存根。

我的代码

describe('GET /v1/search/videos/categories', () => {
  let categoryCreateStub;
  let categoryLoadStub;
  let categoryGetDataStub;
  let getTotalVideoStub;

  beforeEach(() => {
    req = httpMocks.createRequest({
      url: '/v1/search/videos/categories',
      method: 'GET'
    });

    sandbox = sinon.sandbox.create(); // use sandbox for multiple stubs
    categoryLoadStub = sandbox.stub(Categories.prototype, 'load');
    categoryGetDataStub = sandbox.stub(Categories.prototype, 'getData');
    getTotalVideoStub = sandbox.stub(Video, 'getTotalVideos');
    searchFindByCategoryIdStub = sandbox.stub(Search, 'findByCategoryId');
  });

  afterEach(() => {
    sandbox.restore(); // just need to call this to restore
  });

  it('should return a 200 if success', async () => {
    categoryLoadStub.resolves([{
      "_id": new ObjectId()
    }]);
    categoryGetDataStub.resolves([{
      "_id": new ObjectId()
    }, {
      "_id": new ObjectId()
    }]);
    getTotalVideoStub.resolves(10);
    searchFindByCategoryIdStub.resolves(); // resolve this promise too! 

    await searchController.getAllVideosByCategory(req, res);

    expect(res.statusCode).to.equal(200);
  });
});

希望对您有所帮助。