Testing a whole page redirect in qUnit

允我心安 提交于 2019-12-01 04:09:33

Here's how I ended up solving it. giggity.navOnChange is the function analogous to redirect in the original question.

Code:

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;
};

Test code:

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
});

I'm using the giggity object as a namespace for my code. I assign the giggity.window variable to point to window, and interact with window via giggity.window. This way, I can easily mock out any manipulation of the window object. I point giggity.window to a mock object, call the function that modifies giggity.window and check the value of the mock.

You can't modify window.location.href without reloading the page. But if you absolutely want to test these kind of functions it requires a bit of logic modification.

Example #1:

You could do this with two functions, one can be simple redirectTo function similar to yours, and the other can be the one that has the logic of building and url. Like this:

// 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) function is so simple that you will always know that it works without testing.
  2. buildUrl(someParameters) function can contain logic for building an URL, and you should test this. And you can test this without the page redirecting.

Example #2:

You can also write a cross-between these two:

// 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";
}

The above example will have the similar form as your original function, but having the URL building logic function that you can actually test.

Not an example, but #3:

On the other hand if you don't want to change your logic and you have a function simple as this it's no biggie if you just don't test it...

What you are looking to do is best done at integration or acceptance test level, not unit test level. Otherwise you end up with fake browsers and then you are not testing real world, and not really testing anything.

You can open up and iframe on the same domain as the tests and load your code in there. Then you will be able to assert with asynchronous tests.

However qUnit doesn't really seem to have all the tools you would need for that, so if you are looking to test more than a few things that require page reload/navigation, you should use a different testing tool.

The alternative as other posters have mentioned is to mock out the location object and test the behaviour of your code (rather than the browser).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!