Why I think Jest is better than Mocha & Chai
Tags: javascript, testing, beginners, codenewbie
Published: 2021-01-20 00:07:25

So recently i've been working on building services in NodeJS with Typescript, and one of the big challenges i've had is picking a test framework that suits my purpose.

Coming from a .NET Developer backend world and stepping into the NodeJS/Typescript backend world, has been on a journey on its own, and one that I will look to document soon in an upcoming blog post.

However, with my experience on the frontend and using jest to test components and logic, etc. I naturally drifted towards it, but I thought instead I would give Mocha & Chai a shot instead.

## What is Jest or Mocha!?

Jest and Mocha are both examples of testing frameworks that have their pros and cons, but in essence, do the same thing. Just one simpler than the other... 🙄

"*Jest is a JavaScript testing framework maintained by Facebook, Inc. designed and built by Christoph Nakazawa with a focus on simplicity and support for large web applications. It works with projects using Babel, TypeScript, Node.js, React, Angular, Vue.js and Svelte"*

"*Mocha is a JavaScript test framework for Node.js programs, featuring browser support, asynchronous testing, test coverage reports, and use of any assertion library."*

## Why would I want to use either of these?

When building applications using modern javascript libraries or frameworks such as Node or React, you need to be able to test your codebase. Both of these tools enable you to do that, but exposing different API's in order to execute your tests. 

Typically Mocha pairs with Chai:

"*Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework."*

However, when using Jest you will not need to rely explicitly on a third-party assertion library. Let's see some live examples so we can see how the underlying API's differ between the two.

## Implementation Comparisons

### Scenario 1:

I want to unit test my login service on the action of checking the user has a valid userId.

### Mocha

```jsx
import { expect, should } from 'chai';
import loginService from './loginService';

describe('loginService', () => {
	it('should return true if valid user id', () => {
		expect(loginService.isValidUserId('abc123')).to.be.true;
	});
};
```

### Jest

```jsx
import loginService from './loginService';

describe('loginService', () => {
	it('should return true if valid user id', () => {
		expect(loginService.isValidUserId('abc123')).toBeTruthy();
	});
};
```

As you can see from the basic scenario that has been given there isn't a whole lot of difference in the approaches here. It's more a question of personal preference on their assertion APIs in my opinion.

### Scenario 2:

I want to unit test my user service on the action of getting their profile.

### Mocha

*Side note: For us to be able to mock out external modules in Mocha, we are going to need to install another package called 'sinon'. This will allow us to set spies on certain functions and also replace functions with mock ones.*

```jsx
import { expect, should } from 'chai';
import sinon from 'sinon';
import loginService from './loginService';
import userRepository from '../repositories/user';

describe('loginService', () => {
	it('should fetch a user profile given a user id', () => {
		const expectedReturnObject = {
			id: 'abc123',
			username: 'joebloggs97'
		};
		const getStub = sinon.stub(userRepository, 'get');
		getStub.returns(expectedReturnObject);

		const response = loginService.getUserProfile(expectedReturnObject.id);
		expect(response).to.equal(expectedReturnObject);
		expect(getStub.calledOnce).to.be.true;
	});
};
```

### Jest

```jsx
import loginService from './loginService';
import userRepository from '../repositories/user';

const mockGet = jest.fn(() => {
	return {
			id: 'abc123',
			username: 'joebloggs97'
		};
});

jest.mock('../repositories/user', () => {
    return {
      get: mockGet
    };
});

describe('loginService', () => {
	it('should fetch a user profile given a user id', () => {
		const expectedReturnObject = {
			id: 'abc123',
			username: 'joebloggs97'
		};

		const response = loginService.getUserProfile(expectedReturnObject.id);
		expect(response).toEqual(expectedReturnObject);
		expect(mockGet).toHaveBeenCalledOnce();
	});
};
```

As you can see here in the first example with mocha we are fairly reliant on 3 libraries to achieve what Jest can do itself. Also, I feel the APIs of Sinon combined with chai really do make for much more difficult reading as opposed to jest. From a quick glance, it's obvious what Jest is asserting, whereas in the Mocha sample. To me, it takes a lot more from a glance to understand what assertions are taking place.

### So now we know what the options are, how they are used, what is their documentation like?

Well quite honestly having used both Jest was a lot easier to navigate and find answers to. Just like their API's, everything is fluent and a breeze working with Jest. It seems like as well the community is a lot larger and a lot more problems have been solved around the web. Making it easier to google issues. Compared to the 3 different libraries with their own documentation in the Mocha implementation. It can be a bit tricky to know which one to look at and how to use google with them.

## Closing Thoughts

Overall both of these solutions achieve the same goal, just they approach the problem differently. Personally, I have used Jest a lot longer than the Mocha alternative and for me, the simplicity of setting up and implementing Jest is a lot easier than Mocha.

### Helpful Links:

Jest: [https://jestjs.io/en/](https://jestjs.io/en/)

Mocha: [https://mochajs.org/](https://mochajs.org/)

Chai: [https://www.chaijs.com/](https://www.chaijs.com/)

SinonJs: [https://sinonjs.org/](https://sinonjs.org/)

Let me know in the comments below your thoughts and experiences! 👇