Learn React: Jest Testing

Mason Aviles
3 min readMar 5, 2024

--

Jest is a delightful JavaScript Testing Framework with a focus on simplicity. It works out of the box for any React project and is well-suited for testing any JavaScript code. It provides all you need for creating tests, asserting results, and mocking dependencies. Below we expand upon the initial concepts, delve into best practices for testing with Jest, and explore advanced usage scenarios.

Understanding Jest Tests

The it() and test() Functions

Jest tests are defined using the it() (or test(), interchangeably) function. Each test is isolated, allowing you to describe specific functionalities of your code.

it('sums numbers correctly', () => {
expect(2 + 2).toBe(4);
});

Handling Asynchronous Code

Jest provides seamless support for testing asynchronous code. You can use done callback, Promises, or async/await syntax depending on the nature of the asynchronous operations you're testing.

Callbacks

it('calls the callback with the correct data', done => {
const callback = (data) => {
try {
expect(data).toBe('expected data');
done();
} catch (error) {
done(error);
}
};

fetchData(callback); // Assume fetchData is an asynchronous function
});

Promises

it('resolves with the correct data', () => {
return expect(fetchData()).resolves.toBe('expected data'); // Assume fetchData returns a Promise
});

Async/Await

it('awaits the correct data', async () => {
const data = await fetchData(); // Assume fetchData returns a Promise
expect(data).toBe('expected data');
});

Mocking

Mocking is a crucial part of testing in Jest. It allows you to isolate the piece of code you’re testing by replacing its dependencies with mock implementations.

Mocking Functions

const mockFunction = jest.fn().mockReturnValue('mocked value');

it('uses the mock function', () => {
expect(mockFunction('input')).toBe('mocked value');
expect(mockFunction).toHaveBeenCalledWith('input');
});

Mocking Modules

Jest enables you to mock entire modules, which is particularly useful when you need to control module behavior for testing purposes.

Manual Mocks

Create a __mocks__ directory next to the module you wish to mock and provide a mock implementation there. Use jest.mock() to use the mock in your test file.

// Assuming we're mocking a utility module
jest.mock('./path/to/utilityModule');

it('uses the mocked module', () => {
const { utilityFunction } = require('./path/to/utilityModule');
expect(utilityFunction()).toBe('mocked return value');
});

Automatic Mocks with jest.mock()

jest.mock('axios');

it('fetches data with axios', async () => {
const axios = require('axios');
axios.get.mockResolvedValue({ data: 'mocked data' });

const data = await fetchData(); // Assume fetchData uses axios
expect(data).toBe('mocked data');
});

Best Practices

  • Clear and Descriptive Tests: Name your tests clearly and describe the expected behavior. Use describe blocks to group related tests.
  • Isolate Tests: Ensure tests are independent. Clear mocks, reset modules, and clean up the DOM in beforeEach or afterEach if necessary.
  • Code Coverage: Aim for high test coverage but focus on testing the critical paths of your code. Use Jest’s coverage tools to identify untested parts.
  • Test Behavior, Not Implementation: Test what your code does, not how it does it. This approach ensures your tests are resilient to implementation changes.

Jest transforms testing JavaScript code into an easy and enjoyable process, encouraging good testing practices and providing a comprehensive toolset for tackling complex testing scenarios. Whether you’re testing simple functions, asynchronous code, or mocking dependencies, Jest offers a robust solution for ensuring your code behaves as expected.

--

--

Mason Aviles

Sr. Full Stack Engineer who specializes in the Front End