【问题标题】:Unit testing NodeJS Promise inside a function在函数内对 NodeJS Promise 进行单元测试
【发布时间】:2018-05-13 06:14:02
【问题描述】:

我正在尝试对调用 promise 的函数进行单元测试...

使用摩卡,诗乃。我有一个这样的功能块:

我的文件.js:

    let OuterDependecy = require('mydep');
    function TestFunction(callback) {
        OuterDependency.PromiseFunction().then(response => {  

       //some logic here
     }).catch(err => {callback(err)});

在我的测试中,我使用proxyquire 来模拟外部依赖

testfile.js

let proxyquire = require('proxyquire');
let OuterDepStub = {};
let testingFunc = proxyquire('myfile.js', {'mydep': OuterDepStub});

...然后在我的测试块内

    let stubCallback = function() {
                console.log('Stub dubadub dub'); //note...i can use sinon.spy here instead
    };

   beforeEach(()=>{
            OuterDependency.PromiseFunction = function(arg) {
               return  new Promise((resolve, reject)=>{
                   reject('BAD');
               });
            };


            spy = sinon.spy(stubCallback);
       });

我的实际测试现在调用主要的“testfunction”

it('Catches Errors, and calls back using error', done => {
            TestFunction(stubCallback);
            expect(spy).to.have.been.called;
            done();
        });

我看到存根被调用(控制台日志,因此我不想使用 sinon.spy)但间谍说它没有被调用。并且单元测试失败。

我相信这可能是由于在我的测试运行后承诺正在解决的某种竞争条件......无论如何都会延迟测试直到我的承诺得到解决。

我知道在 angularjs 承诺测试中,有一种方法可以“勾选”承诺,以便在您需要时解决。在nodejs中可能吗?

【问题讨论】:

    标签: javascript node.js unit-testing mocha.js


    【解决方案1】:
    • 有没有办法推迟测试,直到我的承诺得到解决。

    据我了解您的问题,是的,您应该只在承诺完成后致电done()。为此,您需要两件事:

    1- 强制TestFunction 返回一个 Promise,这样你就可以等到它解决:

        function TestFunction(callback) {
         return OuterDependency.PromiseFunction().then(response => {
    
            //some logic here
        }).catch(err => { callback(err) });
    }
    

    2- 等待该承诺解决,然后致电done

    it('Catches Errors, and calls back using error', done => {
        TestFunction(stubCallback).then(() => {
            expect(spy).to.have.been.called;
            done();
        })
    });
    

    现在,我们的then 块直到TestFunction 中的catch 块才会运行,所以如果测试按预期工作(即触发块并触发回调),期望并且 done 调用将始终在回调被调用后触发

    • 我看到存根被调用(控制台日志,因此我不想使用 sinon.spy),但间谍说它没有被调用。并且单元测试失败。

    那是因为您的期望在TestFunction 调用之后立即运行,而无需等待它解决。但是,它在最近被调用,因此console.log 出现在下一个规范中。

    【讨论】:

    • 太糟糕了!当你尝试时有人改变了吗?喜欢console.log 语句的顺序吗?你确定TestFunction 真的失败了吗?
    • 我检查了 webstorm 调试测试...我的假设是正确的,存根部分在我的单元测试之后被调用。测试函数确实失败了(即它确实调用了存根)
    • @nate 上面的答案大部分是正确的,但你需要使用.catch(),而不是.then(),因为在你的存根中你拒绝了承诺。请参阅此 SO 答案,尽管还有其他方法可以执行拒绝捕获:stackoverflow.com/questions/28704791/…
    • 是的@DanielT。你是对的……那行得通。尽管在 nodejs 中似乎没有办法“全局”解决承诺,但它仍然很糟糕,因此您不必从主函数返回承诺
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 2021-01-03
    • 1970-01-01
    相关资源
    最近更新 更多