在qUnit中测试整页重定向

时间:2011-08-30 08:39:52

标签: jquery unit-testing testing mocking qunit

我有以下功能

var redirect = function() {
    window.location.href = "http://www.google.com";
}

我想使用qUnit来测试这个函数。

问题是,当我调用运行测试的HTML文档时,只要它进入调用redirect()的测试,浏览器就会加载google.com。我想做的是以某种方式模拟window.location.href,以便它不重定向,因此我可以检查它是否设置为正确的值。

以一种更可测试的方式重写它将是一个可接受的答案,并受到欢迎。由于我使用的是qUnit,因此一些jQuery魔法是合适的,就像一些老式的重构一样。建议为window.location.href添加自定义setter,但我无法弄清楚如何使其工作。

请不要改变我的代码行为的建议。

3 个答案:

答案 0 :(得分:3)

以下是我最终解决问题的方法。 giggity.navOnChange的功能类似于原始问题中的redirect

代码:

var giggity = giggity || {};

$(document).ready(function() {
    $("#branches").change(giggity.navOnChange);
    $("#tags").change(giggity.navOnChange);
});

giggity.window = window;

giggity.navOnChange = function() {
    giggity.window.location.href = this.value;
};

测试代码:

var giggity = giggity || {};

test("giggity.navOnChange", function() {
    var temp = giggity.window
    giggity.window = { location: {} };
    var mockSelect = {
        value: "/link/to/some/branch",
        onChange: giggity.navOnChange
    }
    mockSelect.onChange();
    equal(giggity.window.location.href, mockSelect.value);
    giggity.window = temp; // restore mocked variable
});

我正在使用giggity对象作为我的代码的命名空间。我指定giggity.window变量指向window,并通过windowgiggity.window互动。这样,我可以轻松地模拟对window对象的任何操作。我将giggity.window指向模拟对象,调用修改giggity.window的函数并检查模拟的值。

答案 1 :(得分:2)

如果不重新加载页面,则无法修改window.location.href。但如果您绝对想要测试这些功能,则需要进行一些逻辑修改。

示例#1:

你可以用两个函数做到这一点,一个可以是类似于你的简单redirectTo函数,另一个可以是具有构建和url逻辑的函数。像这样:

// this function is so simple that you never need to unit test it
var redirectTo = function(url)
{
    window.location.href = url;
}

// if this function has any logic worth testing you can do that without redirects
var buildUrl = function(someParameters)
{
    // ....
    // here be some logic...
    // ....

    return "http://www.google.com";
}
  1. redirectTo(url)函数非常简单,您将始终知道它无需测试即可运行。
  2. buildUrl(someParameters)函数可以包含用于构建URL的逻辑,您应该对此进行测试。并且您可以在没有页面重定向的情况下进行测试。
  3. 示例#2:

    您还可以在这两者之间进行交叉编写:

    // don't test this function as it will redirect
    var redirect = function()
    {
        window.location.href = buildUrl();
    }
    
    // if this function has any logic worth testing you can do that without redirects
    var buildUrl = function()
    {
        // ....
        // here be some logic...
        // ....
    
        return "http://www.google.com";
    }
    

    上面的示例将具有与原始函数类似的形式,但具有您可以实际测试的URL构建逻辑函数。

    不是一个例子,而是#3:

    另一方面,如果你不想改变你的逻辑并且你有一个简单的功能,那么如果你不测试它就没什么大不了的......

答案 2 :(得分:1)

您希望做的最好是在集成或验收测试级别,而不是单元测试级别。否则你最终会使用虚假的浏览器,然后你就不会测试真实的世界,也不会真正测试任何东西。

您可以在与测试相同的域上打开和iframe,然后在其中加载代码。然后,您将能够使用异步测试进行断言。

然而,qUnit似乎并没有真正需要的所有工具,所以如果你想要测试多个需要页面重新加载/导航的东西,你应该使用不同的测试工具。

其他海报提到的替代方案是模拟位置对象并测试代码的行为(而不是浏览器)。