Как проверить перенаправление javascript без перенаправления?
Я использую Jasmine для некоторого тестирования, хотя это обычно можно применить к тестированию на основе JavaScript на основе браузера.
У меня есть функция, которая при определенных условиях перенаправляет пользователя на другую страницу с помощью window.location.assign
. Проблема в том, что если эта строка достигнута, страница перенаправляется. В этом случае, поскольку он перенаправлен на '/'
, страница перезагружается, и все тесты снова запускаются. Что я могу сделать, чтобы проверить, что функция достигает линии, в которой она перенаправляется, без перенаправления?
Ответы
Ответ 1
Я столкнулся с этой же проблемой. Мое решение состояло в том, чтобы развернуть фактическое перенаправление в одну целевую функцию. То есть, не делайте никаких проверок условий или другой логики, просто перенаправляйте.
Скажем, это старый код...
function redirect() {
if(something) {
window.location = "/";
else if(somethingElse)
window.location = "/?a=42";
else
window.location = "/derp";
}
Я бы изменил это на..
function redirect() {
if(something) {
doRedirect("/");
else if(somethingElse)
doRedirect("/?a=42");
else
doRedirect("/derp");
}
function doRedirect(href) {
window.location = href;
}
Затем вы можете spyOn
использовать функцию doRedirect
, чтобы гарантировать, что функция переадресации передается в правильном URI для условий.
Ответ 2
Здесь полный пример тестирования того, что нажатие кнопки покупки перенаправляет пользователя на внешний URL, используя упомянутый метод @Morgan.
# navigation.coffee
exports.goToExternalUrl = (url) ->
window.location = url
# myView.coffee
Navigation = require("lib/navigation")
exports.MyView = Backbone.View.extend
events:
"click .purchase":"purchase"
purchase: ->
Navigation.goToExternalUrl("http://amazon.com/someproduct")
# my_view_spec.coffee
Navigation = require("lib/navigation")
MyView = require("myView").MyView
describe("MyView"), ->
it "can be purchased", ->
# this line prevents the location.href from actually being set
spyOn(Navigation,'goToExternalUrl').andCallFake (->)
$el.find('.purchase').trigger('click')
expect(Navigation.goToExternalUrl).toHaveBeenCalled()
Ответ 3
Трудность здесь в том, что ваш код зависит от глобальной переменной window
, поэтому вы не можете легко заменить эту зависимость в своем тесте. Вот основная идея того, что я сделал в подобной ситуации. Напишите свой код, чтобы window
был доступен только косвенно, за исключением случаев инициализации, где он сохраняется в локальной переменной/экземпляре.
var unit = {
initialize: function () {
this.window = window;
},
codeThatRedirects: function (newUrl) {
this.window.location.href = newUrl;
}
};
Теперь вы можете заменить unit.window
на что-то еще, возможно, так:
unit.initialize();
unit.window = {
location: {
href: "dummy"
}
};
unit.codeThatRedirects('http://new.url.com');
assert(unit.window.location.href === "http://new.url.com");
Ответ 4
Вы можете использовать GreaseMonkey для обновления javascript, но это остается несколько навязчивым...