目前我正在为使用nodejs
编写的服务器端代码编写一些单元测试。
现在,我的情况是我的自定义模块正在使用其他模块,我的或nodejs
标准库,我想模仿它们。首先,我搜索了一些现有解决方案,例如我发现:https://github.com/thlorenz/proxyquire和https://github.com/mfncooper/mockery。
但是今天我尝试使用天真的做法并做这样的事情:moduleUnderTest
var fs = require('fs');
exports.foo = function(){
console.log("===foo===");
fs.read();
}
和档案moduleUnderTestSpec
:
var fs = require('fs');
var moduleUnderTests = require('../server/moduleUnderTests.js');
fs.read = function(){
console.log("===read===");
}
当我运行grunt jasmine_node
时,我可以看到:
===foo===
===read===
所以在这个简单的例子中,我可以将fs
模块中的一个函数换成另一个函数。有什么情况我的方法不起作用吗?
答案 0 :(得分:5)
首先看一下sinon因为它可以帮助你轻松地模拟或删除函数。
当您require
Node.js中的模块时,模块将根据docs on modules进行缓存。
我在您的解决方案中遇到的唯一问题是,如果您需要使用真实的fs.read
,您将无法将其丢失。例如,您可以像这样使用Sinon;
var fs = require('fs');
var sinon = require('sinon');
// mock fs.read
sinon
.stub(fs, 'read')
.returns("string data");
// test your code that uses fs.read
assert(fs.read.calledOnce);
// then restore
fs.read.restore();
答案 1 :(得分:2)
您的方法没问题,但只有在模块导出对象时它才有效。如果一个模块导出函数(发生了很多)或其他任何东西,你就无法模拟它。也就是说,您只能模拟模块对象的属性,而不能模拟整个对象。