如何对调用另一个返回承诺的函数进行单元测试? [英] How to unit test a function which calls another that returns a promise?

查看:25
本文介绍了如何对调用另一个返回承诺的函数进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 express 4 的 node.js 应用程序,这是我的控制器:

I have a node.js app using express 4 and this is my controller:

var service = require('./category.service');

module.exports = {
  findAll: (request, response) => {
    service.findAll().then((categories) => {
      response.status(200).send(categories);
    }, (error) => {
      response.status(error.statusCode || 500).json(error);
    });
  }
};

它调用我的服务并返回一个承诺.一切正常,但我在尝试对其进行单元测试时遇到了麻烦.

It calls my service which returns a promise. Everything works but I am having trouble when trying to unit test it.

基本上,我想确保根据我的服务返回的内容,我使用正确的状态代码和正文刷新响应.

Basically, I would like to make sure that based on what my service returns, I flush the response with the right status code and body.

因此,对于 mocha 和 sinon,它看起来像:

So with mocha and sinon it looks something like:

it('Should call service to find all the categories', (done) => {
    // Arrange
    var expectedCategories = ['foo', 'bar'];

    var findAllStub = sandbox.stub(service, 'findAll');
    findAllStub.resolves(expectedCategories);

    var response = {
       status: () => { return response; },
       send: () => {}
    };
    sandbox.spy(response, 'status');
    sandbox.spy(response, 'send');

    // Act
    controller.findAll({}, response);

    // Assert
    expect(findAllStub.called).to.be.ok;
    expect(findAllStub.callCount).to.equal(1);
    expect(response.status).to.be.calledWith(200); // not working
    expect(response.send).to.be.called; // not working
    done();
});

当我正在测试的函数返回一个 promise 时,我已经测试了类似的场景,因为我可以在 then 中挂钩我的断言.

I have tested my similar scenarios when the function I am testing returns itself a promise since I can hook my assertions in the then.

我也尝试用 Promise 包装 controller.findAll 并从 response.send 解决它,但它也不起作用.

I also have tried to wrap controller.findAll with a Promise and resolve it from the response.send but it didn't work neither.

推荐答案

您应该将断言部分移到 res.send 方法中,以确保在断言之前完成所有异步任务:

You should move your assert section into the res.send method to make sure all async tasks are done before the assertions:

var response = {
   status: () => { return response; },
   send: () => {
     try {
       // Assert
       expect(findAllStub.called).to.be.ok;
       expect(findAllStub.callCount).to.equal(1);
       expect(response.status).to.be.calledWith(200); // not working
       // expect(response.send).to.be.called; // not needed anymore
       done();
     } catch (err) {
       done(err);
     }
   },
};

这篇关于如何对调用另一个返回承诺的函数进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆