javascript 如何在不重定向的情况下测试javascript重定向?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6154011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test javascript redirection without redirecting?
提问by Mario
I'm using Jasmine for some testing, although this can be generally applied to browser-based javascript unit testing.
我正在使用 Jasmine 进行一些测试,尽管这通常可以应用于基于浏览器的 javascript 单元测试。
I have a function that, on certain conditions redirects the user to a different page using window.location.assign
. The problem is, if this line is reached, the page is redirected. In this case, since it's redirected to '/'
, the page reloads, and all the tests run again. What can I do to test that the function reaches the line where it redirects, without redirecting?
我有一个功能,在某些条件下,使用window.location.assign
. 问题是,如果到达这一行,页面将被重定向。在这种情况下,由于它被重定向到'/'
,页面会重新加载,并且所有测试都会再次运行。我能做些什么来测试函数是否到达了它重定向的行,而不重定向?
回答by Morgan ARR Allen
I have faced this same problem. My solution was to break out the actual redirect into a single purpose function. That is, don't do any condition checking or other logic, just redirect. Say this is the old code...
我也遇到过同样的问题。我的解决方案是将实际重定向分解为单一用途的功能。也就是说,不要做任何条件检查或其他逻辑,只是重定向。说这是旧代码...
function redirect() {
if(something) {
window.location = "/";
else if(somethingElse)
window.location = "/?a=42";
else
window.location = "/derp";
}
I would change that to..
我会把它改成..
function redirect() {
if(something) {
doRedirect("/");
else if(somethingElse)
doRedirect("/?a=42");
else
doRedirect("/derp");
}
function doRedirect(href) {
window.location = href;
}
Then you can spyOn
the doRedirect
function to ensure the redirect function is passing in the correct URI for the conditions.
然后,您可以使用spyOn
该doRedirect
函数来确保重定向函数为条件传递正确的 URI。
回答by Derek Dahmer
Here's a full example for testing that clicking a purchase button redirects the user to an outside URL using the method @Morgan mentioned.
这是一个完整的示例,用于测试单击购买按钮使用@Morgan 提到的方法将用户重定向到外部 URL。
# 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()
回答by speedarius
The difficulty here is that your code depends on a global variable, window
, so you can't easily replace that dependency in your test. Here's the basic idea of what I did in a similar situation. Write your code so that window
is only ever accessed indirectly, except during initialization where it gets saved off into a local / instance variable.
这里的困难在于您的代码依赖于一个全局变量window
,因此您无法在测试中轻松替换该依赖项。这是我在类似情况下所做的基本想法。编写您的代码,以便window
只能间接访问,除非在初始化期间将其保存到本地/实例变量中。
var unit = {
initialize: function () {
this.window = window;
},
codeThatRedirects: function (newUrl) {
this.window.location.href = newUrl;
}
};
Now you can replace unit.window
with something else, maybe like this:
现在你可以unit.window
用其他东西替换,也许像这样:
unit.initialize();
unit.window = {
location: {
href: "dummy"
}
};
unit.codeThatRedirects('http://new.url.com');
assert(unit.window.location.href === "http://new.url.com");
回答by atk
You might consider using GreaseMonkey to update the javascript, but this remains somewhat intrusive...
您可能会考虑使用 GreaseMonkey 来更新 javascript,但这仍然有些侵入性......