7

我有以下功能

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

我想用 qUnit 测试这个函数。

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

以更可测试的方式重写它将是一个可接受的答案,并受到欢迎。因为我使用的是 qUnit,所以一些 jQuery 魔法是合适的,一些老式的重构也是如此。建议为 window.location.href 添加一个自定义设置器,但我不知道如何让它工作。

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

4

3 回答 3

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,并与windowvia交互giggity.window。这样,我可以轻松地模拟出对window对象的任何操作。我指向giggity.window一个模拟对象,调用修改giggity.window并检查模拟值的函数。

于 2011-10-20T09:04:31.123 回答
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 的逻辑,您应该对此进行测试。您可以在没有页面重定向的情况下对此进行测试。

示例 #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:

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

于 2011-10-20T06:10:10.473 回答
1

您要做的最好在集成或验收测试级别完成,而不是单元测试级别。否则你最终会得到假的浏览器,然后你就没有测试现实世界,也没有真正测试任何东西。

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

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

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

于 2014-04-12T10:32:44.627 回答