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

时间:2011-05-27 14:55:23

标签: javascript unit-testing jasmine

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

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

4 个答案:

答案 0 :(得分:19)

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

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。

答案 1 :(得分:1)

以下是一个完整的测试示例,单击购买按钮可以使用@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()

答案 2 :(得分:1)

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

答案 3 :(得分:-1)

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