Testing in JavaScript: Mocha and Chai

Henna Singh
4 min readMay 2, 2022

#BuildTogether Day 85/100

Today was a holiday from work and ended up a productive day. We enjoyed a good English breakfast, walked along the coast, and paid a visit to Pet Store to see the bunnies we are planning to buy šŸ˜

Letā€™s talk about testing in JavaScript.

What is Unit Testing?

Unit testing means testing the behavior of code in small, independent units. Units are typically designed to be the smallest meaningful chunk of independently testable code. This is in comparison to integration testing, in which a set of modules are tested as a group.

Mocha and Chai, Test Suites and Test Cases

Mocha and Chai are two JavaScript frameworks commonly used together for unit testing.

Mocha is a testing framework that provides functions that are executed in a specific order, and that logs their results to the terminal window.

The tests written in Mocha use the keywords describeand it. These keywords, provided by Mocha, provide structure to the tests by batching them into test suites and test cases.

A test suite is a collection of tests all relating to a single functionality or behavior. A test case or a unit test is a single description of the desired behavior of the code that either passes or fails. Test suites are batched underneath the describekeyword, and test cases are batched under the itkeyword.

Additionally, Mocha provides tools for cleaning the state of the software being tested in order to ensure that test cases are being run independently of each other.

Sometimes other tools are used to stub or mock the desired behaviors of other units that a given unit of code might interact with. The independence of test cases is a key principle of unit testing, as it allows the cause of errors to be pinpointed more specifically if a test case fails, thereby speeding up the debugging process.

Assertions

The base component of test cases is assertions. Assertions are tied to particular values (whereas test cases are descriptions of behavior) and they will fail if the expected value does not match the actual value.

Every assertion in a test case must be met in order for the test case to pass.

Chai is an assertion library that is often used alongside Mocha. It provides functions and methods that help compare the output of a certain test with its expected value. Chai provides clean syntax that almost reads like English!

Example of a Chai assertion: expect(exampleArray).to.have.lengthOf(3);

This code will check whether the variable exampleArray has a length of three or not.

Failing and Passing Tests

Robust tests are accurate for both failing and passing conditions! When writing tests, make sure that the test fails if the feature that it is testing was not implemented properly, as well as making sure that the test passes if it is. Tests that will erroneously pass can be enormously misleading and might lead to broken code getting merged and deployed.

Reading Tests with Mocha and Chai

Do you remember the Rock, Paper, Scissors project I did in previous posts. Below is a sample test example for the project.

Test Suites

Tests for one feature are grouped together in describe blocks. This group of tests, called a test suite, describes the ā€œMain Functionalityā€ of the setPlayerMoves function. Describe takes a string and a callback function: the string describes the feature or behavior being tested, and the callback function contains all of the code for the different tests being run.

Inside the describe block, the afterEach function is called. This is called a hook, or a function that is called at certain points in the lifecycle of the process that it is running in. The afterEach function gets called right after each it block is run, and customizing this function allows to reset things that we want to reset between different tests.

Here the function clearMoves which is a helper function that sets all of the moves back to undefined. It is written outside of any of the blocks, but used as a hook in many of them.

function clearMoves() {
playerOneMoveOneType = undefined;
playerOneMoveOneValue = undefined;
playerTwoMoveOneType = undefined;
playerTwoMoveOneValue = undefined;
}

Itā€™s important for tests to generally start from a clean slate and for each test to be independent of the others, because the errors from the tests give us a specific diagnosis of what is wrong with the code.

Test Cases

Each it block describes more particular behavior to test. The first it block, test that setPlayerMovesactually exists and that it is a function so that it can correctly be used in the next block.

In the second it block, the function setPlayerMovesisis called which is a function from the code that we are testing from Rock, Paper, Scissors game. After setPlayerMoves is called with the arguments, the variable playerOneMoveOneType should be equal to the string ā€˜rockā€™ and playerOneMoveOneValue should be equal to the number 11.

Assertions

Any individual assertion where there is a comparison between the actual and expected values can be called an assertion. The words should, expect, and assert in the tests indicate that an assertion is being made.

Each it block test includes multiple assertions because there are multiple scenarios and edge cases that we would test for. The error messages from failed tests will most likely point to one of these assertions.

Learn more from the mocha and chai documentation.

PS: If you wanna be part of my 100 Days journey, feel free to drop by ;)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Henna Singh
Henna Singh

Written by Henna Singh

Technical Speaker and an aspiring writer with avid addiction to gadgets, meet-up groups, and paper crafts. Currently doing Full Stack Diploma at Code Institute

No responses yet

Write a response