TDD with Mocha

Joseph Harwood
3 min readJul 26, 2019

--

Test-driven development(TDD) is a crucial skill for testing your code and preventing bugs in your application. This blog post will be an easy way to get started using the most popular Javascript testing framework, Mocha.

Before getting started, it is important to understand why you would want to use TDD. TDD is an approach to writing software where you write tests before you write code. The basic steps are:

  1. Red: Write a test and make sure it fails.
  2. Green: Write the simplest, easiest possible code to make the test(s) pass.
  3. Refactor: Optimize and/or simplify the code to make the test(s) pass.

Your First Test

Install Mocha globally with:

npm install -g mocha

Create a directory and test.js to run the tests:

mkdir mocha
touch test.js

Run npm init and set ‘test command:’ to ‘mocha’ so that we can run tests with ‘npm test’.

Copy this into test.js:

const assert = require('assert')describe('Math', function() {
it('should test if 5*3 = 15', function(){
assert.equal(15, 5*4)
})
it('should test if (2-1)*6 = -6', function(){
assert.equal(-6, (2-2)*6)
})
})
  • describe() is simply a way to group our tests.
  • it() is used for an individual test case.
describe('string name', function(){
// can nest more describe()'s here, or tests go here
it('should do something', function(){
assert.equal("return value", "way to get the solution")
})
})

This happens when we run ‘npm test’:

0 passing (11ms)2 failing1) Mathshould test if 5*3 = 15:AssertionError [ERR_ASSERTION]: 15 == 20+ expected - actual-15+20at Context.<anonymous> (test.js:5:14)2) Mathshould test if (1-2)*6 = -6:AssertionError [ERR_ASSERTION]: -6 == -12+ expected - actual--6+-12at Context.<anonymous> (test.js:8:14)

Take a moment and think about how we could make these tests pass.

The solution is very simple:

const assert = require('assert')describe('Math', function() {
it('should test if 5*3 = 15', function(){
assert.equal(15, 5*3)
})
it('should test if (1-2)*6 = -6', function(){
assert.equal(-6, (1-2)*6)
})
})

Now we get:

Math✓ should test if 5*3 = 15✓ should test if (1-2)*6 = -62 passing (8ms)

Method Test

Next let’s make a test that checks if our multiply method returns the correct solution for 2 numbers in the arguments passed in.

Create app.js for our multiply method and copy this:

let obj = {}obj.multiply = function(x, y) {
if(!Number.isInteger(x) && !Number.isInteger(y)) return undefined;
return x+y
}
module.exports = obj

obj is being exported with module.exports so that our testing file, test.js, can tell JavaScript what object to return as the result of a require call.

Test.js looks like this now:

const obj = require('./app.js')
const assert = require('assert')
describe('Math', function() {
it('should test if 5*3 = 15', function(){
assert.equal(15, 5*3)
})
it('should test if (1-2)*6 = -6', function(){
assert.equal(-6, (1-2)*6)
})
})
describe('Multiplication', function() {
describe('multiply', function() {
it('should multiply 5 and 1 to equal 5 ', function() {
assert.equal(5, obj.multiply(5,1));
})
})
})

This happens when we run ‘npm test’:

Multiplicationmultiply1) should multiply 5 and 1 to equal 52 passing (19ms)1 failing1) Multiplicationmultiplyshould multiply 5 and 1 to equal 5 :AssertionError [ERR_ASSERTION]: 5 == 6+ expected - actual-5+6at Context.<anonymous> (test.js:16:14)

Take a moment and think about how we could make these tests pass.

I got you with the same trick again! You really should read what you are copy and pasting before you add it to your project ;).

The solution:

let obj = {}obj.multiply = function(x, y) {
if(!Number.isInteger(x) && !Number.isInteger(y)) return undefined;
return x*y
}
module.exports = obj

Conclusion

I hope that this blog post is a good introduction to Mocha and TDD for you. The best way to really get the TDD concept is to write tests before you work on a feature for your project. Try to get the test to pass in the most basic way possible, then refactor your code to have a more elegant solution.

Good luck!

Sources

--

--

No responses yet