So, I'm new to testing in js and I'm trying to use mocha to test a node application.
Ideally I'd like to have it so that the tests are in a separate file and are run on the node script itself (perhaps by use of a require call at the top of the test script). At the moment I'm doing something which I know can't be right which is to include the tests in a block at the bottom of the script file. The problem with this being test code included in production code and the fact that it comes back with 'describe is not defined' when you try to start the node server.
I've read lots of tutorials on mocha, etc and it seems that you can export all of your methods individually by doing 'module.export.', but that seems costly and is also obtrusive.
What am I missing here? Surely you don't have to construct two scripts (one with and one without the test code?) - that would end up with version issues.
How is this best done (links to articles also gratefully accepted. :)
Thanks
James
So here's what I see people doing, and the method I've adopted in my own work:
test
directory and place all of your test cases in it. Use whatever naming convention you like. I prefer to have one test file for each source module. At the start of each file, simply require the module under test.--recursive
argument so it knows to examine the entire contents of your test
directory.This means you are testing the modules through their interfaces, just as you would use them in normal code. The downside is, if you have non-exported functions with execution paths which are difficult to hit via the module's interface, you may find yourself a little frustrated.
On one hand, I agree with the notion that modules should be tested as they are used. On the other hand I think I'd sleep better at night knowing that I directly tested every one of the aforementioned tricky execution paths. Prior to doing node.js programming I spent several years writing erlang code, which has the exact opposite convention: (tests are placed at the end of the source files so they have direct access to every function in the module, and testing includes/exports are handled by ifdef directives). Personally, I like the erlang approach better.
Anyway, I hope this was helpful. If anyone reading this has a strong opinion to the contrary I'd love to hear it.
I agree with David Weldon's post, but I'm going to add some examples.
You should be writing your Node modules as normal. If I'm writing a Calculator that might be used in other parts of the code my Calculator module might look something like this:
Calculator = {
add: function(a, b) {
return a + b;
}
};
module.exports = Calculator;
You mention that using module.exports
seems costly and obtrusive. There are a couple of things you can do about this. module.exports
is the best and recommended way to have your code accessible in another file. To make it simple you can wrap your functions and variables in an object as I did with the Calculator and only export the one object.
Note that there are two ways to use "exports". You can do this:
var a = function() { ... };
var b = 10;
var c = null;
exports.a = a;
exports.b = b;
exports.c = c;
Which adds things to the special exports
object for the module. Or you can do this:
objectToExport = {
a: function() { ... },
b: 10,
c: null
};
module.exports = objectToExport;
Which will replace the exports
object. If you did exports = objectToExport
it wouldn't work and you would end up with an empty object when you tried to require
the module in another file.
When I test with Mocha I put all my test files in a test
directory that mirrors the structure of my code directories.
project
+- lib
+- calculator.js
+- test
+- lib
+- calculator.js
My test/lib/calculator.js file is my Mocha tests for the lib/calculator.js file
var Calculator = require('../../lib/calculator.js');
var assert = require('assert');
describe('Calculator', function() {
describe('add', function() {
it('should add two numbers', function() {
var res = Calculator.add(2,2);
assert.equal(res, 4);
});
});
});
By default mocha will look for the /test
directory in the directory you run mocha. If you have subdirectories like in the example above you can add --recursive
to the command line to find all your tests. So if you running in the project
directory above your command would be mocha --recursive
.