Sinon - 如何存根嵌套函数?

时间:2014-12-13 19:33:42

标签: node.js request mocha sinon chai

道歉,如果这是一个简单的问题,我对Node和Sinon来说相对较新。我正在努力弄清楚如何断言在Nodejs中调用嵌套的异步函数。

我正在使用mocha,chai,sinon和request(https://github.com/request/request),但我认为我遗漏了一些关于存根部分的基本内容。

my_app.js中的示例 -

var request = require('request');

function MyModule() {
};

MyModule.prototype.getTicker = function(callback) {
    request('http://example.com/api/ticker', function(error, response) {
        if (error) {
            callback(error);
        } else {
            callback(null, response);
        }
    });
};

exports.mymodule = new MyModule();

在测试中。我正在尝试将请求的调用存根,并提供一些虚拟数据返回。但是我在创建存根的行上不断收到“请求未定义”的错误。

var myApp = require('../my_app.js')
    ,assert = require("assert")
    ,chai = require('chai')
    ,sinon = require('sinon')
    ,expect = chai.expect;

describe('mymodule object', function() {

    var mymodule = myApp.mymodule;

    before(function(done) {
        sinon.stub(request).yields(null, JSON.stringify({
            price: '100 USD'
        }));
        done();
    });

    it('getTicker function should call request on example ticker', function(done) {
        mymodule.getTicker(function(error, result){
            request.called.should.be.equal(true);
            done();
        });
    });

});

我知道我可以分配sinon.stub(objname,“funcname”)或sinon.stub(“funcname”),但是那些只设置了外部对象,我正在尝试存根函数内部的函数请求getTicker。

关于如何做到这一点的任何想法?也许我也需要使用间谍(但是如何?)或者是否有更好的方法来测试上面的getTicker函数?

1 个答案:

答案 0 :(得分:7)

您收到的是未定义的消息,因为request变量在测试范围内是未知的。但是,即使您要更正此并将request库分配给变量,您仍会收到错误,因为sinon需要在任何提供的对象上使用方法才能创建存根。

这样的结果是request函数本身不能被存根,因为它不存在于对象上,而是作为定义其他方法的函数。因此,为了支持可测试性,最好不要在代码中直接使用request,而是使用其附加的方法,然后可以对其进行存根。例如:

<强> my_app.js

MyModule.prototype.getTicker = function(callback) {
  request.get('http://example.com/api/ticker', function(error, response) {
    ...
  });
};

<强> my_test.js

var request = require('request');

before(function() {
  sinon.stub(request, 'get').yields(null, JSON.stringify({price: '100 USD'}));
});

it('getTicker function should call request on example ticker', function() {
  mymodule.getTicker();
  request.get.called.should.be.equal(true);
});

(请注意,当存根是同步的时,不必异步运行mocha。)