Chai with Mocha: Unit Testing in Node.js

Anjali
8 min readJul 4, 2021

When we write tests for small individual components like a function or a file of the entire code base, that’s Unit Testing. For writing unit tests, we’ll pick up one functionality/logic and mock the bits on which that one functionality depends.

This might be sounding absurd.

However, read along, this will make sense in just a minute.

For understanding what I meant by mocking, we’ll have to first understand testing in general.

Made this using Figma

This above picture is also known as what is called the testing pyramid. You can read about end to end tests and integration tests here and here. Since now we know about different types of tests, let’s come back to unit tests and mocking.

As discussed above, unit tests are used to test the smallest functions or code snippets. Most of the time, the individual functions depend on other pieces of code.

While writing unit tests, we want to focus on that one functionality to verify that it is working and not worry about its external dependencies. To do that, we use replacement code that simulate the working of those external dependencies. Unit tests are fast, requires no database and can be easily written with the help of mocking.

Mocking

We saw what are unit tests? But why do we even need testing in the first place? Isn’t writing code just enough that we now need to test it?

  • Firstly, writing tests ensures that whatever code we write, it works and does not have any bugs.
  • If we go back to update our code, it makes it easy for us(or some other developer) to understand the logic and saves a lot of time.
  • For testing code we need to write code that can be tested. So, we might as well learn to write clean code in the process.

For anyone who is interested in a little back story.

Why did I decide to learn about testing?

I am working on a project Deck. Me and my teammate had to demo it in a meeting. However, just an hour before the meeting, we encountered a bug, solving that led to another bug(:))and soon we realised that we have broken the thing beyond repair in a scope of an hour.

Not to mention that we blew the meeting. :)) That’s when we decided upon two things:

  • Stop debugging a few hours before important meetings :’D
  • Learn about testing and write tests.

So, here I am writing about writing tests for Node.js using Mocha.

What is Mocha?

From Mocha docs:

Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.

Now, let’s have a look at the syntax

describe(): In Mocha, we have the global describe function, it takes in two parameters, a string and a callback function. The string is the description of the test. We group tests using describe. This function should tell what is it that you are testing. And as we can see in the code snippet below, we can further subdivide this by creating subgroups. So, for example, the outer describe is for one file then the inner describe will be for one function.

it(): Similarly, we have the it function. It is used to write single tests. It takes two parameters, a string and a callback. The string is the description of the test and the callback has the actual code for the test.

Let’s walk through the snippet above. Suppose we have a file which has functions to perform basic arithmetic operations. Level 0(outermost)describe function is for that. Then I have subdivided it into individual functions of add and subtract, level 1 describe functions. And finally, we have the it functions in which we test multiple cases of addition and subtraction.

One thing to be noted here is that all the it statements in the above code begin with should.

It’s not mandatory to write it like this but its a convention. So that when you read the entire thing together it resembles a readable sentence. If we take the first it() in the above example, this is how I would read it: “Arithmetic operations add should give sum of two numbers”

Reading the ones highlighted should resemble a natural language sentence

Now, let’s see how to actually test code.

Below is the result of above tests:

Quite evidently, the one with green tick is our passing test and one in red is the failing one.

Now, the obvious question, where do we write tests? There are multiple conventions for the testing directory but till now whatever tests I wrote, they were in the same directory, alongside the file to be tested with the extension .spec.js. For example, if the file to be tested is named math.js then the test file is math.spec.js.

So, if you are going for a similar convention to test the files when writing next to the actual unit, one needs to use a configuration. In the package.json you’d have to add something like this that works for your folder structure.

"scripts": {
"test": "mocha './app/**/*.spec.js'"
}

Here’s the one I created for this blog

Chai

Now just run the command:

npm test

And viola! You are all set.

One more thing before having Chai. (Sorry, I could not stop myself from writing this. XD)

Mocha Reporters

There are many Mocha reporters for writing tests with efficiency. However the watch mode is what I have used till now. Running npm test every time to run unit tests can be tedious, a more effective way is using watch mode. We can put the the watch flag in package.json as given below.

//we can use the watch flag like this
"scripts": {
"test": "mocha --watch"
}
//or like this"mocha": {
"watch":true
}
//or we can make a separate file altogether and write the configurations in that

Now, let’s have Chai! Not the beverage(though that would be good. Yes, I am lame), the assertion library.

What is Chai?

Mocha is a tool used for unit testing, another important thing required is an assertion library. In simple words, an assertion library lets you interrogate pieces of your code and tells you what and where the problem lies(assuming there is a problem).

Note: I recently came to know that there is an inbuilt assertion library as in Node.js as well called Assert.

Install Chai with the command:

npm i -D chai

Let’s have a look at the syntax:

There are multiple assertion styles like expect, should and assert in Chai and all of them have their uses. We’ll just have a look at expect for now. We can import expect in the file and use it as demonstrated below.

Expect assertion style in Chai

We’ve had enough of the syntax.

Now lets write some tests(and we’ll talk about a few bits of syntax while going through the tests):

Here is the file(testing.js) that we are going to test:

used Carbon to make this

Let’s quickly walk through the code. But before that, lets keep in mind that we shouldn’t club pieces of code/functions that do not have any relation with each other whatsoever into a single file. This is just for demonstration purpose.

Staring from the most basic function, getSum() that returns the sum of two numbers.

isValidEmail(): uses a regex pattern to check if the email given to it has the correct format or not.

getName(): Takes in the email id of a person and extracts the name of the company from it. For example: “john@mycompany.com” will return “mycompany”

getFactorial(): I think the name is quite a good explanation that it returns the factorial of a given number.

Here’s the test file(testing.spec.js)

used Carbon to make this

Let’s understand what is happening here

The first describe function ‘testing’ (level 0) is representing the entire file testing.js. It has nested describe functions for individual functions of that file(level 1). And then comes the it functions that has the actual code testing the logic and functionality by creating some mock variables.

Lets talk about a few of these in detail and the others will make sense on it’s own.

‘getSum’ describe function has two values n1 and n2 in the it function. We are importing the function getSum on the top of the file and passing values and checking if it is equal to the correct answer which is 11 in this case. We can even write multiple tests for this if we want.

Similarly, we are importing the function isValidEmail on the top of the file, the ‘isValidEmail’ describe function is taking in a value which is an email id and passing it to the function. If the email is valid the function will be equal to true and in case it is not valid, it will be false and the test will fail.

Here’s the picture of my terminal showing the result of these tests.

Look the the watch flag working to make my work easy by waiting for the changes :p

You can see that the tests are passing. But don’t just take my word for it(or a picture of my terminal). Try it yourself and play around with the code to see if this actually works or not.

You can view the code from this blog post in this GitHub Gist.

Here are a few resources that helped me:

Chai, Mochajs.org, Unit testing and Mocking, Regex pattern, Regex101.

I read from various resources and I have added a few above as it’s not possible to mention all the links. However, I will add all that I remember even in the future.

All of the content above covers some basic elements of testing using Mocha and Chai. And this blog post has become quite long. There are other things like mocha hooks, testing async code and using mocha for testing REST API in Node.js and I’ll write about them in another blog and link it below.

One can always learn more and these are my interpretations of these concepts. If you find that something was not explained in a correct way, do tell me, it will help me improve my understanding. I’ll take all constructive feedback(be it for the concepts or for the article) positively.

If you liked this, do share it. You can connect with me on Twitter or Polywork.

Thank You for reading!

--

--

Anjali

Don't play with Jazbaat, play with JavaScript instead. It's actually fun. If you already follow me, please don't unfollow me because of this bio.