如何在不重定向的情况下测试javascript重定向?

发布于 2024-11-10 03:13:37 字数 231 浏览 1 评论 0原文

我使用 Jasmine 进行一些测试,尽管这通常可以应用于基于浏览器的 javascript 单元测试。

我有一个函数,在某些条件下使用 window.location.assign 将用户重定向到不同的页面。问题是,如果到达此行,页面将被重定向。在这种情况下,由于它被重定向到 '/',因此页面会重新加载,并且所有测试都会再次运行。我可以做什么来测试函数是否到达重定向的行(不重定向)?

I'm using Jasmine for some testing, although this can be generally applied to browser-based javascript unit testing.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不必了 2024-11-17 03:13:37

我也遇到过同样的问题。我的解决方案是将实际的重定向分解为单一用途的函数。也就是说,不做任何条件检查或其他逻辑,只是重定向。
假设这是旧代码...

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状况。

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.

寻梦旅人 2024-11-17 03:13:37

这里的困难在于您的代码依赖于全局变量 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");

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.

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.initialize();
unit.window = {
  location: {
    href: "dummy"
  }
};

unit.codeThatRedirects('http://new.url.com');

assert(unit.window.location.href === "http://new.url.com");
咆哮 2024-11-17 03:13:37

下面是一个完整的示例,用于测试单击购买按钮将用户重定向到使用 @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()

Here's a full example for testing that clicking a purchase button redirects the user to an outside URL using the method @Morgan mentioned.

# 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()
﹉夏雨初晴づ 2024-11-17 03:13:37

您可能会考虑使用 GreaseMonkey 来更新 javascript,但这仍然有些干扰......

You might consider using GreaseMonkey to update the javascript, but this remains somewhat intrusive...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文