【问题标题】:Mocha testing a bluebird powered node style callbackMocha 测试 bluebird 驱动的节点样式回调
【发布时间】:2015-06-07 09:37:47
【问题描述】:

我在通过运行 mocha 来通过测试时遇到了麻烦,这似乎正在通过。

测试:

describe('.get()',function() {

    it('should be called once',function() {
        // => Need to spy on this
        var callback = function(err,data) {
            console.log('I am called');
            if (err) {
                console.log('I am logging the error '+err);
            } else {
                console.log('I am logging the data '+data);
            }
        }

        agentMock._response = {body:'something',headers:'headers'};

        // => Start Spying
        var spy = sinon.spy(callback);
        sinon.spy(agentMock,'get');

        baseRequest.get(spy); // refer (a) below

        expect(agentMock.get).to.have.been.calledOnce;
        expect(spy).to.have.been.calledOnce;
        expect(spy).to.have.been.calledWith(null,'data');
    });
});

我想测试callback 是否被调用。因此,我登录了回调的主体,标准输出也表明它正在被调用。

标准输出:

  .get()
    1) should be called once
I am called
I am logging the data something


  0 passing (15ms)
  1 failing

  1) .get() should be called once:
     AssertionError: expected spy to have been called exactly once, but it was called 0 times

详情:

(a) baseRequest.get 将数据作为bluebird 承诺返回。这可以通过将nodeback 本身传递给.get 或在.get 调用之后链接.then 来使用。

BaseRequest.prototype.get = function(callback) {
    // inner details

    return invokeandPromisify(request,callback);
}

function invokeandPromisify(request, callback) {
    return new Promise(function(resolve,reject) {
    // Invoke the request
    request.end(function(err,result) {

        // Return the results as a promise
        if (err || result.error) {
            reject(err || result.error);
        } else {
            resolve(result);
        }
    });
    }).nodeify(callback); // to have a node style callback
}

发生这种情况是因为我想要 spy回调 被传递给不同的函数(invokeandPromisify 这里)并且间谍丢失了吗?我只是解释一下。

问候。

【问题讨论】:

    标签: javascript node.js mocha.js sinon bluebird


    【解决方案1】:

    由于baseRequest#get 返回一个承诺,我会在承诺解决后做出断言。

    请看下面的例子:

    it('should be called once',function(done) {
        // => Need to spy on this
        var callback = function(err,data) {
            console.log('I am called');
            if (err) {
                console.log('I am logging the error '+err);
            } else {
                console.log('I am logging the data '+data);
            }
        }
    
        agentMock._response = {body:'something',headers:'headers'};
    
        // => Start Spying
        var spy = sinon.spy(callback);
        sinon.spy(agentMock,'get');
    
        baseRequest.get(spy).finally(function() {
          expect(agentMock.get).to.have.been.calledOnce;
          expect(spy).to.have.been.calledOnce;
          expect(spy).to.have.been.calledWith(null,'data');
          done();
        });
    
    });
    

    【讨论】:

    • 谢谢,拯救了我的一天!您能否详细说明这里的问题是什么,因为我已经通过设置 agentMock._response 的值来设置响应。
    • 之后不是同步测试吗?我不明白。
    • Promise 是异步的,所以你的测试也必须是异步的。我使用#finally 来确保在promise 解决时做出断言,然后调用done() 来表示异步测试的结束。
    • 是的,终于明白了。
    【解决方案2】:

    您的测试应通过添加完成设置为异步。然后在你的回调函数中调用 done()

    请查看http://mochajs.org/#asynchronous-code

    【讨论】:

    • agentMock._response = {body:'something',headers:'headers'}; 立即设置响应。那么,它现在是异步的吗?
    猜你喜欢
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2022-07-23
    • 2014-06-23
    相关资源
    最近更新 更多