Angular JS-тестирование функции с редиректом страницы с использованием Karma / Jasmine
У меня есть функция в моем угловом контроллере, которая выглядит следующим образом:
$scope.myFunction = function(){
$scope.myVariable = "something";
$scope.myOtherVariable = "something else";
window.location.href = "/path/to/page";
}
Простой тест жасмина охватывает вышеуказанную функцию и выглядит следующим образом:
describe('my test', function(){
it('should pass', function(){
scope.myFunction();
expect(scope.myVariable).toBe('something');
expect(scope.myOtherVariable).toBe('something else');
});
});
Вышеописанный тест сам проходит, но затем карма выбрасывает в консоль следующую ошибку:
Некоторые из ваших тестов сделали полную перезагрузку страницы!
Перенаправление страницы вызывает карму, чтобы поднять это предупреждение. Как лучше всего это обойти?
Я подумал о том, чтобы дать оба анонимных функции в тесте Jasmine и угловые имена, а затем с помощью arguements.callee.caller.name внутри исходной функции, чтобы определить, вызывается ли функция сама по себе или жасмин. К сожалению, arguments.callee.caller.name всегда возвращает undefined, что, как я подозреваю, вызвано тем, как Angular и Jasmine связаны друг с другом.
2 ответа:
Уже давно этот вопрос не задавался, но следующий подход должен быть чище:
Изменив исходную функцию на использование сервиса $window от Angular вместо объекта browser window, можно написать тест, который не требует изменения производственного кода или учета каких-либо параметров среды выполнения. Это, конечно, требует, чтобы $window была зависимостью для контроллера, в котором находится функция.Используя angular-mocks/ngMock , что-то например:
var fakeWindow = { location: { href: '' } } // instantiate controller with mock window beforeEach(inject(function($controller) { $controller('YourCtrlName', { $window: fakeWindow }); }));
Должен позволить тесту Пройти, предполагая, что контроллеру не нужно $window ни для чего другого.
Можно просто создать функцию, которая выполняет навигацию, например
$scope.Navigate = function() { window.location.href = "/path/to/page"; };
Или даже лучше в какой-то службе
app.factory('navigator', function() { return { Navigate: function(path) { window.location.href = path; } }; });
Затем в своем тесте вы можете использовать шпиона для навигации, чтобы убедиться, что навигация была вызвана, но на самом деле не вызывайте навигацию.