我有以下功能
var redirect = function() {
window.location.href = "http://www.google.com";
}
我想使用qUnit来测试这个函数。
问题是,当我调用运行测试的HTML文档时,只要它进入调用redirect()
的测试,浏览器就会加载google.com。我想做的是以某种方式模拟window.location.href,以便它不重定向,因此我可以检查它是否设置为正确的值。
以一种更可测试的方式重写它将是一个可接受的答案,并受到欢迎。由于我使用的是qUnit,因此一些jQuery魔法是合适的,就像一些老式的重构一样。建议为window.location.href添加自定义setter,但我无法弄清楚如何使其工作。
请不要改变我的代码行为的建议。
答案 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
,并通过window
与giggity.window
互动。这样,我可以轻松地模拟对window
对象的任何操作。我将giggity.window
指向模拟对象,调用修改giggity.window
的函数并检查模拟的值。
答案 1 :(得分:2)
如果不重新加载页面,则无法修改window.location.href。但如果您绝对想要测试这些功能,则需要进行一些逻辑修改。
你可以用两个函数做到这一点,一个可以是类似于你的简单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";
}
您还可以在这两者之间进行交叉编写:
// 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构建逻辑函数。
另一方面,如果你不想改变你的逻辑并且你有一个简单的功能,那么如果你不测试它就没什么大不了的......
答案 2 :(得分:1)
您希望做的最好是在集成或验收测试级别,而不是单元测试级别。否则你最终会使用虚假的浏览器,然后你就不会测试真实的世界,也不会真正测试任何东西。
您可以在与测试相同的域上打开和iframe,然后在其中加载代码。然后,您将能够使用异步测试进行断言。
然而,qUnit似乎并没有真正需要的所有工具,所以如果你想要测试多个需要页面重新加载/导航的东西,你应该使用不同的测试工具。
其他海报提到的替代方案是模拟位置对象并测试代码的行为(而不是浏览器)。