如何使用sinon来模拟作为函数导出的节点模块的函数/属性?
我有一个作为function导出的服务模块。 我需要传递一些东西,像一个configuration对象,所以它需要保留这个结构。 我正在尝试从服务中删除一个函数,但无法弄清楚。 在我的应用程序,我有一个函数,使testing期间有问题的API调用,所以我想存根。 (我知道我必须写我的testing不同来处理asynchronous问题)
// myService.js module.exports = function(config) { function foo() { returns 'bar'; } return { foo: foo }; }; // test.js var config = require('../../config'); var request = require('supertest'); var chai = require('chai'); var expect = chai.expect; var sinon = require('sinon'); var myService = require('./myService.js')(config); describe('Simple test', function(done) { it('should expect "something else", function(done) { var stub = sinon.stub(myService, 'foo').returns('something else'); request(server) // this object is passed into my test. I'm using Express .get('/testRoute') .expect(200) .expect(function(res) { expect(res.body).to.equal('something else'); stub.restore(); }) .end(done); }); }); * /testRoute I set up as a simple GET route that simply returns the value from myService.foo()
以上不起作用,我相信这与我的服务出口的方式有关。 如果我写如下服务,存根工作正常。
module.exports = { test: function() { return 'something'; } };
但是,我又需要能够将信息传递给模块,所以我想将模块保留在上面的原始结构中。 有没有一种方法来存储以这种方式导出的模块中的函数? 我也正在寻找代理,但不知道这是否是答案。
testing存根不起作用的原因是foo
函数每次调用模块初始化函数时都会创build。 正如你发现的那样,当你在模块上有一个静态方法时,你就可以存根。
这个问题有多种解决scheme,但最简单的方法是静态地公开方法。
// myService.js module.exports = function(config) { return { foo: foo }; }; var foo = module.exports.foo = function foo() { return 'bar' }
这是丑陋的,但工程。
如果foo函数对服务中的variables有一个闭包(这就是它存在于服务初始化程序中的原因)。 那么不幸的是,这些需要明确的传入。
// myService.js module.exports = function(config) { return { foo: foo }; }; var foo = module.exports.foo = function(config) { return function foo() { return config.bar; } }
现在,您可以安全地存根模块。
但是,如何剔除应该被认为是不安全的。 只有当你的testing完美的工作,存根被清理。 您应该始终在before
(或before
和after
)夹具存根,如:
// We are not configuring the module, so the call with config is not needed var myService = require('./myService.js'); describe('Simple test', function(done) { beforeEach(function () { // First example, above this.myStub = sinon.stub(myService, foo).returns('something else'); // Second example, above this.myStub = sinon.stub(myService, foo).returns(function () { returns 'something else'; }); }); afterEach(function () { this.myStub.restore(); }); it('should expect "something else", function(done) { request(server) // this object is passed into my test. I'm using Express .get('/testRoute') .expect(200) .expect(function(res) { expect(res.body).to.equal('something else'); }) .end(done); }); });
还有其他选项可以使用dependency injection来存根相关性。 我build议你看看https://github.com/vkarpov15/wagner-core或我自己的https://github.com/CaptEmulation/service-builder
- 在javascript中测量websockets数据input/输出的大小
- 我如何dynamic生成JavaScript /节点中的testing用例?
- 摩卡/ Should.js使用asynchronousfunction
- 如何在testing过程中存储node.js内置的fs?
- 分离unit testing和集成testing
- 在suback / tape中使用“plan”和“end”的目的是什么?
- jsPerf.com Chrome浏览器的结果对于Node.js基准是否可靠?
- 摩卡'每个挂钩'消息之前红色。 我怎么知道具体是什么错误?
- 摩卡柴Sinontesting无法访问的承诺/asynchronous/事件发射器