Testing with Mocha and Chai

hetvibhansali
Spider R&D
Published in
6 min readNov 25, 2020
Photo by Scott Graham on Unsplash

Testing is all about ensuring that every line of the code written is executed along with checking for possible bugs.

Do you know that software testing is actually a huge topic and there are different types of testing?

Well, let's quickly have a look before we proceed.

Image by H2K Infosys

So, we see that it's broadly classified into static and dynamic testing. In static testing, the project documents are reviewed to identify errors, whereas in dynamic testing, as the name suggests, the software is tested during execution.

Unit testing is a good practice. It makes the code cleaner along with reducing the chances of errors during runtime, making sure that the software meets the quality standards.

This helps programmers indulge in Test-Driven Development (TDD) and Behaviour-Driven Development (BDD).

Test-driven development includes writing a particular test before production and checking whether it’s working. The idea is basically to get a little bit of assurance from the initial test. This helps the programmer to refactor the code and make it clean.

Behaviour-driven development is a subtopic of test-driven development but instead uses simple and human-readable descriptions of software user requirements as the basis for tests.

But what exactly is Unit testing?

A unit here can be literally anything that we may want to test- a class, a method, or just a line of code. The smaller, the better! That's because smaller tests give you a granular view of how your code is performing. Also, practically, smaller tests take less time to execute, thus testing a thousand of them in a second.

Now, you might think, “why do we need to unit test the code when console logging can solve most of the errors?”

Well, it can be a bit cumbersome as well as tiring when we are working with a huge codebase. That's where testing gains its importance in development!

In this article, we are mainly going to learn about Unit testing with Mocha and Chai.

Getting Started

Let's learn about unit testing our code using Mocha, which is a light-weight Node.js test framework, and Chai, which is a TDD assertion library for node.

Image by hackernoon.com

Both Mocha and Chai run in NodeJs and the browser and allow asynchronous testing. Although Mocha can be paired with any of the assertion libraries, it is delightfully paired with Chai most of the time.

Chai provides us with several APIs like Assert, Expect/Should, and more. Mocha provides all the functionality required for automated testing in simpler ways.

Now that we’ve got a rough understanding of what is testing like, let's get our hands dirty with some code!

Setting up the project...

So, here we have a simple NodeJs project set up with the app.js file as the main script file, and a test directory, which will have the corresponding test files. Here, the appTest.js has the tests for the app file.

Let's install both chai and mocha as dev dependencies.

npm install --save-dev

Add the test script in the package.json file.

"scripts": {
"test": "mocha"
}

The app.js file has the code to be tested.

Here, we have a Chef which can cook all the dishes mentioned in the dishes array.

The function checkMenu returns any random dish from the array. Now we are going to test the functionality of this function.

Let's write our tests in the appTest.js file in the test directory. By default, Mocha will look for the test directory for test files.

Just like any other node project, we will require the library and our code from the app file. The assert in chai is similar to the assert module in node, with some extra sugar.

The ‘describe’ method takes in two arguments, a label describing what the test is about, and a function, that will do all the testing. We use the ‘it’ method which again takes two parameters a label of the test and a function, that uses the methods of the assert module.

Here, we are doing two tests, one for testing if the checkMenu function returns a string using the isString method, and another for testing if the dish returned, is one of the dishes array. We do this by using the oneOf method.

Now, let's run npm run test or npm test in our terminal and see what happens...

Both tests are passing!

Yay! We have successfully passed both tests! Now, let's see when our test can fail. So, we add an integer in the dish variable in the app.js file.

let dish = 3;

Let's test now, using npm run test command.

Both the tests have failed :(

Oops! Both of our tests have failed. Wanna know why?

The dish variable, that we added, was an integer. So, it isn't a valid dish name (not a string) and also isn't one of the dishes in the dishes array.

Okay, now let's try and add some more functionality to our Chef, and try out some more tests.

So, we have added a new functionality to our chef, the number of customers he can cook for in a day. He can serve five customers in his restaurant, which is described in the customersFed function. We serve customers till they become more than five, and return a message accordingly when the chef can't cook anymore.

Okay, now time to test this function.

Here, we check if the chef can feed more customers by running the customersFed function five times and testing what happens when the customer count reaches 0. We do this by making use of the isAtLeast method, which takes in two parameters, the object to be tested, and its minimum value.

Let's have a look at the terminal...

Yay! All our tests passed.

So, we can see that our chef has completed his job of serving the five customers successfully.

Illustration by all-free-download.com

Our very first testing project seems to work well!

But there is some more we can do with the tests. What if we just want to test one of them at a time?

Well, we use the ‘skip’ method for that.

We add it.skip(label, function()) for that. Let's add that in the first two tests and see what happens.

As expected, we are getting one passing, and two pending tests. The third test has passed.

Quite simple. Isn't it?

Conclusion

These are just a few methods from a large number of methods and functions which we can use in any of our node.js or javascript projects.

There are a lot more libraries and frameworks that can be used for testing projects. Cypress, Enzyme, SinonJS, jest, SuperTest, etc are some. Most of them are free and easy to implement in any Javascript-based project.

I hope that this has gives you a basic understanding of what unit testing looks like. Make sure to try and exploit these libraries in your projects and take a step towards automated testing and better programming as a whole!

--

--