In association with heise online

Initialise test context

Since Mocha can handle the aforementioned containers and tests with nested callbacks, generic test aspects can easily be implemented using common JavaScript language elements. For example, any local variables that are defined within a container will be available to all containers and tests that are located in this container.

Mocha knows the setup and teardown functions that initialise and terminate such aspects. They will be executed before or after each individual test that is located in the same container or in a subcontainer.

suite('fizzBuzz', function () {
var _fizzBuzz;
setup(function () {
_fizzBuzz = new FizzBuzz();
});
teardown(function () {
_fizzBuzz = undefined;
});
suite('isFizz', function () {
// ...
});
suite('isBuzz', function () {
// ...
});
});

If the BDD style is used instead of TDD, these functions will be called beforeEach and afterEach. In the BDD style, Mocha knows the additional before and after functions that will only be executed once per container. However, the framework doesn't provide any equivalent functions for TDD.

Assert, should, expect and that

One element of Mocha is that it is agnostic over which assert module is in use. Therefore. as well as the default Node.js assert module, there are further modules that distinguish themselves through a different syntax and a higher level of convenience:

should, like Mocha and Express, was created by TJ Holowaychuk. This module's preferred syntax is perfectly suited for the BDD style that Mocha uses by default. As the verb "should" plays an important role in the naming of tests in this style, it is natural to write code like:

actual.should.eql(expected);

The main disadvantage of should is that the applied syntax can cause runtime errors if the actual variable contains the undefined value: in this case, should will try to access a nonexistent property, which can only result in failure – but not in a controlled way.

The expect module avoids this disadvantage by applying a different syntax. As it only uses the actual variable as a function parameter, the previously described error can't occur:

expect(actual).to.eql(expected);

A completely different approach is taken by the node-assertthat module that was created by the author of this article. This module uses the same syntax as the NUnit test framework for .NET and places emphasis on maintaining good code readability:

assert.that(actual, is.equalTo(expected));

Testing asynchronous code

At first glance, Mocha makes testing asynchronous code just as easy as testing synchronous code. If, for example, instead of

test('returns true for numbers divisible by 3', function () {
var actual = fizzBuzz.isFizz(3);
assert.that(actual, is.true());
})

the asynchronous code

test('returns true for numbers divisible by 3', function () {
fizzBuzz.isFizz(3, function (actual) {
assert.that(actual, is.true());
});
});

is used, the test – assuming that the isFizz function is implemented correctly – will also run successfully and be marked accordingly. Unfortunately, however, testing asynchronous code isn't actually quite as simple, because the mentioned test will always be successful regardless of whether the implementation is correct.

The reason for this is that after calling the isFizz function, Mocha doesn't know that there is another callback pending, and that it needs to wait for it. As the test has seemingly arrived at the end without triggering an exception, it will be marked as successful. The result of the assert function that is then executed in the callback will arrive too late to have an impact.

Mocha provides a very elegant way of solving this: asynchronous tests accept the done parameter in their callbacks. Behind this parameter, there is another callback. When it is encountered, Mocha will wait until the callback has been executed before it completes the test. Therefore, if our earlier, flawed test is rewritten to say

test('returns true for numbers divisible by 3', function (done) {
fizzBuzz.isFizz(3, function (actual) {
assert.that(actual, is.true());
done();
});
});

Mocha will execute it correctly and wait for the two callback functions to be executed as required.

Next Page: Configuring, browsers and conclusion

Print Version | Permalink: http://h-online.com/-1829727
  • Twitter
  • Facebook
  • submit to slashdot
  • StumbleUpon
  • submit to reddit
 


  • July's Community Calendar





The H Open

The H Security

The H Developer

The H Internet Toolkit