Testing with Mocha - Part 1
Mocha
Mocha is a JavaScript test framework, which runs on Node.js and in the browser as well. Let’s install it first!
I will use Mocha to test code on node, so first, we need to create a folder, navigate to it in the terminal and type npm init –y
, which is short for npm init --yes
. (Alternatively, you can type npm init
and answer the questions but they are not important in this case, so I skip them and accept the default answers.) This will create our package.json
file. (Note: You must have Node.js installed on your computer, so if you haven’t done that yet, please do so.)
Once we have our package.json
set up, head over to the terminal and type npm i mocha –D
or npm install mocha --save-dev
as these two commands are equivalent. Once the installation is complete, you should see mocha with the latest version (4.1.0 at the time of writing this) in package.json
under devDependencies
.
Chai
Every good test case must have at least one assertion. What is an assertion? An assertion is an expression which can evaluate to true or false. If it evaluates to true, the piece of code does what it’s supposed to do and the test passes. If it’s false, there is a bug somewhere in the code and the test fails.
Chai is a cool assertion library, which provides us with a lot of helpful tools to write strong assertions. Chai also runs on Node.js and in the browser and also works well with Mocha.
Let’s install Chai as well. Type npm i chai –D
in the terminal, and the latest version of chai also should appear in the devDependecies
.
Setting up the files
OK, now that we have both Mocha and Chai installed, create a folder called src
, and then we create two files in the src
folder, app.js
and app.test.js
. The file and folder names are not important, it can be anything you like. I usually put the unit test files next to the file that contains the code I want to test, and name it as FILENAME.test.js
.
We will create an array and will test it using Mocha and Chai.
Let’s create our not so difficult array in app.js
first:
const names = ['Alice', 'Bob', 'Carol', 'Dennis'];
We need to make the array available in the test file, so let’s export it:
module.exports = {
names
};
So far so good, so let’s head over to app.test.js
.
Mocha does not need to be required at the top of the file as running the mocha command in the terminal will run our test cases.
Chai comes with various assertion styles and methods. I will use expect
throughout this article, so let’s require it:
const expect = require('chai').expect;
So from now on, whenever we call expect
, we will use chai’s expect
method. We also need the names
array, so let’s require it as well:
const { names } = require('./app);
Writing our first test case
Everything is set up, so we can write our first test:
describe('names array', () => {
it('should be an array with length of 4', () => {
expect(names).to.be.an('array');
expect(names).to.have.lengthOf(4);
});
});
The describe
block organizes the test cases, so we can put similar logic inside one describe
block.
The test case starts with the it
statement. The first argument is what we expect from our code, namely that we want names
to be an array with four elements. The second argument is a function, in which we write our assertions.
We can then beautifully chain our expectation. First, we want names
to be an array, and then we expect it to have a length of 4. It’s very straightforward, isn’t it? The cool thing is that we can use chains to make our assertions more readable. The full list of chains can be found in the Chai documentation.
Running the test
We have our first test case, let’s run the test and see if it passes. Go back to package.json
and enter the following in the scripts
object:
"scripts": {
"test": "mocha src/**/*.test.js"
}
The test
command in the terminal will run mocha on all files in the src
folder which ends in test.js
.
Now head over to the terminal and type npm test
, hit enter and Mocha will run. If everything goes well and why not, you should see the test passing.
We can also see the string we entered in the description of our block of tests from describe
, (names
array) and the name the test case is also displayed.
However, it’s a best practice to test our test.
What? Isn’t that enough?
No. What if we accidentally write a test that always passes regardless of the code? The test will immediately lose its purpose. What’s the point of having such a test?
It’s a good idea to modify the assertion to see if the test fails this time. So change the array to object in app.test.js
:
describe('names array', () => {
it('should be an array with length of 4', () => {
expect(names).to.be.an('object');
expect(names).to.have.lengthOf(4);
});
});
We expect the test to fail as names
is of course an array and not an object. Run the test with npm test
, and indeed, our test fails. Mocha gently warns us that something is not working as expected.
Change the other assertion as well and let’s have a look again:
describe('names array', () => {
it('should be an array with length of 4', () => {
expect(names).to.be.an('array');
expect(names).to.have.lengthOf(5);
});
});
Again, we expect our test to fail, since we have four elements in the array and not five. We can also see the expected result we entered in the assertion (5) and the actual length of the array in the terminal.
This way we can be sure that our test is valid, so any time we change something in the names
array, our test will fail, hence we will be warned if a future change breaks the code.
Conclusion
Mocha is an essential tool for the Node developer. Coupled with chai (or any other assertion library) it’s a powerful way to write tests and make our system more robust. In the next article I will show you some more simple test cases.
Enjoy coding!