Following on from the previous post where I was testing some logical functionality in JavaScript it is possible to see that QUnit can provide simple assertions for logical statements like in other unit testing frameworks. However, there are times when you need to test functions and classes which take in complex objects as parameters as opposed to simple types.
JavaScript perhaps comes in quite strongly because it is not a strongly typed language, which of course has some disadvantages in general, but in terms of unit testing this is a very good thing. Unlike languages like C# where it is very difficult to mock an object without using interfaces or other levels of abstraction, this is not an issue as you can construct any object that conforms to what is being tested irrespective of type. The only major consideration that will come into whether or not something is testable is not manipulating the document in a direct manner (pass in an element triggered on an event rather than directly manipulating the DOM using JQuery). Another consideration will be if you are using AJAX requests you might want to check the functionality around the AJAX request rather than testing the ordinary transmission of data, that is if we are considering unit testing rather than end-to-end testing which QUnit is built for thanks to asynchronous testing (a functionality in QUnit which is also nicely geared towards setTimeout).
Example: let’s consider UI interaction
This again is very simple, it’s just to get across the basic idea of mock objects and QUnit. All we’re going to work towards is to have a div with a blue background, and when you click on it, it will turn red. For the purposes of this let’s look to our unit test class and write our additional tests to the js/tests.js file that we created last time. We’re assuming that all ui functionality will be contained in logic.ui, and we want to see the class change from blue, to red (the element object literal is serving as our mock object).
var element = {
className: 'blue'
};
logic.ui.change_color(element);
ok(element.className == 'red')
});
Run the tests watch them fail and let’s make them pass.
Setting up the CSS with our two classes blue and red respectively:
background-color: #0094ff;
width: 300px;
height: 400px;
}
.red {
background-color: #ff0000;
width: 900px;
height: 1200px;
}
Setting up the HTML page:
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="css/main.css" type="text/css" />
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/logic.js"></script>
<script type="text/javascript" src="js/bindings.js"></script>
</head>
<body>
<div id="box" class="blue"></div>
</body>
</html>
Let’s look to implementing the logic in our logic.js class. Notice we’re creating a new object literal (or a sub object literal) for implementing the new methods.
change_color: function (element) {
element.className = 'red';
}
};
Let’s set up our bindings for JQuery (using bindings.js)
$('#box').bind('click', function () { logic.ui.change_color(this); });
});
Then we’re done. We should see our tests pass. But let’s say that we’re not happy with that and we also want to see it toggle back in the other direction.
Let’s go to js/tests.js again and write another test that will check the opposite direction:
var element = {
className: 'red'
};
logic.ui.change_color(element);
ok(element.className == 'blue')
});
Like last time let’s watch it fail. After that’s established let’s move to refactor our old code inside the change_color method on the logic.ui sub-literal:
change_color: function (element) {
if (element.className == 'blue') element.className = 'red';
else if (element.className == 'red') element.className = 'blue';
}
};
As you watch the tests pass you’ll see that you’ve been using QUnit tests to test your user interface logic in Javascript, you’ll also have seen how easy it is to mock these element objects to do your tasks.
Please comment if you have any questions or if something needs correcting.


