I have the following function
var redirect = function() {
window.location.href = "http://www.google.com";
}
I want to test this function using qUnit.
The problem is, when I call up the HTML document in which my tests run, as soon as it gets to the test that calls redirect()
, the browser loads google.com. What I would like to do is mock out window.location.href somehow so that it doesn't redirect, and so I can check that it was set to the proper value.
Rewriting this in a manner that it would be more testable would be an acceptable answer and is welcomed. Since I am using qUnit, some jQuery magic would be appropriate, as would some old fashioned refactoring. Adding a custom setter for window.location.href was suggested, but I couldn't figure out how to get this to work.
Please, no suggestions of changing the behavior of my code.
QUnit is a JavaScript library to test your JavaScript code. You can write your tests using certain functions provided by QUnit and then have QUnit run them. QUnit can run your tests in the browser or in a plain Node.js process.
QUnit.test (“Should format the products with a price higher than 2000 to Error”, function (assert) { Step 6: Now run the UnitTests.qunit.html file . Right click and select Run as Unit Test in WebIDE. Successfully qUnits are now executed.
Whenever you encounter a Bug/Ticket, start by writing a QUnit that fails first, and then fix the code. Write your tests as small as possible: don't add a statement that is not needed for the test, such as an id in controls, constructor properties. Use fake timers to avoid as many async tests as possible.
QUnit is an open source framework used for writing and running tests. Following are its most prominent features − QUnit provides Assertions for testing expected results. QUnit provides Test fixtures for running tests. QUnit tests allow to write code faster, which increases the quality. QUnit is elegantly simple.
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.
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";
}
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With