让我们说我的代码修改了一个未向用户公开的变量,如下所示:
var model;
module.exports = {
doSomething: function() {
...
//at some point in the code, modify model
if(/* something happened */) {
model = '123';
},
doSomethingElse: function() {
//use model in some way
}
}
};
如果我以后想要编写单元测试以确保model
已更新,但我没有获取它,我该如何测试呢?这可能与Karma / Jasmine / Sinon.js有关吗?
答案 0 :(得分:0)
直接检查模型值是不可能的,因为它隐藏在闭包中。
你仍然可以为它编写测试:你的“模型”会使doSomethingElse
表现不同。调用doSomething
后,您可以验证它是否符合您的期望。这样,您也可以自由重构模块的内部,而无需更改测试用例。
答案 1 :(得分:0)
通常,测试私有方法或属性是反模式。通过将实现的各个方面设为私有,您可以明确地创建自由,以便在不更改公共API的情况下更改这些实现详细信息的工作方式。
因此,在一个理想的世界中,你不应该(在这种情况下,你不能)测试model
值。
尽管如此,我们并不总是生活在一个理想的世界里。因此,如果你真的必须测试私有属性和方法,你可以考虑一些变通方法。
首先,您可以查找环境变量,并导出其他属性(通过将它们附加到exports
)。
var model;
module.exports = {
...
}
if(process.env.ENV === 'TEST') {
module.exports.model = model;
}
第二,您可以使用约定而不是将内容完全隐私。例如,一个常见的约定是使用_
为私有实体添加前缀,以表示它们不是公共API的一部分。根据将使用您的API的受众群体,这可能会有不同程度的有效性。
第三,您可以为私有变量创建访问器,并以某种方式检查测试环境的存在(可能是全局变量,环境变量或注入模块的变量)在实例化时)只允许在检测到测试环境时进行访问。
第四,您可以允许将“督察”对象注入您的模块(此对象仅在测试期间出现)。我使用这种模式取得了一些成功。
module.exports = function(spies) {
...
spies = spies || {};
var model = spies.model;
...
}
...
// instantiate the module in the test
var spies = {};
var mock = new Module(spies);
// do a thing
expect(spies.model).to.eql("foo");
但实际上,您应该重新考虑您的测试策略和设计。