我在js中有这样的代码:
var obj = (function(){
var stateObj = {key:"privateValue"};
return {
getState: function() {
return stateObj.key;
},
publicFn : function(){
//do some operation with stateObj
if(getState() == "test") {
//. . . .
}
}
}
}());
我测试了这样的代码:
//test case
sandbox.stub(obj.getState,"test")
assertItShouldGoInsideIfLoop(obj.publicFn())
然而,在代码审查中,我的团队主管说,这是错误的,他让我使用依赖注入来处理这些情况。
我真的不知道为什么上述方法是错误的,甚至为什么要使用DI。
答案 0 :(得分:2)
如果我正确地解释了这一点,那么问题在于您对调用publicFn
的价值的测试取决于stateObj
的值。依赖注入背后的整个想法是,您提供了一些方法来在测试中提供这些值,以便将数据与被测函数的行为分离。
var obj = (function(){
return {
setStateObj: function(stateObj) {
this.stateObj = stateObj;
},
getState: function() {
return this.stateObj.key;
},
publicFn : function(){
//do some operation with stateObj
if(getState() == "test") {
//. . . .
}
}
}
}());
现在我们可以使用setStateObj
在测试中根据需要设置状态,而不是存储值,这可能是危险的:
obj.setStateObj({ key: 'test' })
assertItExecutesIfStatement(obj.publicFn())
obj.setStateObj({ key: 'blah' })
assertItDoesntExecuteIfStatement(obj.publicFn())
那为什么选择短信getState
?假设我们评论getState
:
getState: function() {
// return this.stateObj.key;
}, // returns nothing, but you're stubbing it to return "test" anyway!
显然,这个功能不起作用,但是对你的存根来说,它会!因此,尽管有非工作代码,你仍然可以通过测试!
这是另一个为依赖注入提供另一个案例的例子。说我有以下功能:
function getDayOfWeek() {
var date = new Date();
var dayNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
return dayNames[date.getDay()];
}
此getDayOfWeek
功能取决于date
。这将是一个噩梦,因为我们无法控制date
的价值。如果我们用提供日期值的方式重写此函数(即注入依赖项),我们可以轻松地检查函数的任何固定日期:
function getDayOfWeek(date) {
date = date || new Date();
var dayNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
return dayNames[date.getDay()];
}
assertEqual('Wednesday', getDayOfWeek(new Date(2015, 0, 1)));
assertEqual('Thursday', getDayOfWeek(new Date(2015, 0, 2)));
// and so on...