Простой ответ, чтобы обойти проблему с этим конкретным тестом, состоит в том, чтобы изменить эту строку:
//spyOn(ctrl.$location, 'path').and.returnValue(mocks);
spyOn(ctrl.$location, 'path').and.returnValue('fakepath');
Редактировать : Просмотр тестируемого кодапохоже, ctrl.$location.path
возвращает разные результаты в зависимости от того, как он вызывается.Если он вызывается без параметров, он возвращает строку.Если он вызывается со строкой в качестве параметра, то он возвращает сам объект ctrl.$location
.Предполагая, что я прав в этом, есть два варианта ...
Первый вариант - просто настроить ваш объект ctrl
для теста, чтобы ctrl.$location.path
не нуждался в мошенничестве (шпионить) вообще, если это возможно.
Второй вариант заключается в реализации логики двойного возврата в вашем шпионе с использованием callFake
:
spyOn(ctrl.$location, 'path').and.callFake(function(arg) {
if (typeof arg == "string") {
return ctrl.$location;
} else {
return "fakepath";
}
});
End Edit
Но я думаю, что вам не хватает некоторых деталей о том, как работают функции spyOn
, поэтому я немного подробнее расскажу!
Когда вы следите за функцией, вы в основном заменяете еефункция со шпионом - так что если вы впоследствии вызовете эту функцию, она ничего не делает по умолчанию.Но вы также можете добавить к своему шпиону - например, вы можете заставить его возвращать определенное значение, или вы можете заставить его идти вперед и вызывать исходную функцию, для которой он стоит.Вот что происходит, когда вы используете spyOn(...).and.returnValue()
и spyOn(...).and.callThrough()
.
Например, допустим, у меня есть этот простой объект, foo
.У него есть функция с именем sayHello
, которая вызывает другую функцию с именем send
, которая отправляет сообщение по сети Бобу.Если сообщение успешно отправлено, счетчик messagesToBob
увеличивается на единицу, в противном случае он остается прежним.(send
возвращает true, если это сработало, или false, если это не сработало).
// Begin contrived example!
var foo = {
messagesToBob: 0,
sayHello: function() {
if (this.send()) {
this.messagesToBob += 1;
}
},
send: function() {
network.send("Bob", "Hello");
}
};
Теперь я хочу это проверить, но, очевидно, я не хочу отправлять Бобу кучу сообщенийво время моих тестов.И вот тут-то и появляется шпион.
spyOn(foo, "send");
По сути, это берет функцию foo.send
и заменяет ее пустой функцией (я думаю, она только что вернула undefined
).
Если я хочу проверить счетчик foo
при успешном запуске, я могу сделать возвращение шпиона «отправка» истинным:
spyOn(foo, "send").and.returnValue(true);
foo.sayHello();
expect(foo.messagesToBob).to.equal(1);
Если я хочу проверить, что не *Приращение 1051 * при неудачной отправке, я могу сделать так, чтобы шпион "send" возвращал false.
В любом из этих случаев я также мог проверить состояние самой функции шпиона, используя expect(...).toHaveBeenCalled()
или * 1055.* (или любые другие функции, доступные для вашей конкретной среды / среды тестирования).
В любом случае, надеюсь, это поможет!Функции вашего «фиктивного» объекта не должны возвращать значение в этом примере (при условии, что вам вообще нужен этот объект), потому что эти функции все равно заменяются шпионами.