Если я интерпретирую это правильно, проблема здесь в том, что ваш тест на значение вызова 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...
Вы имеете в виду вы специально для проверки модульных тестов в 'obj.publicFn'? – Ryan
@minitech: Да, правильно – batman
Какие операции вы делаете, когда это единичный тест? – Ryan