Jest is a popular JavaScript testing framework that simplifies the process of writing and executing tests for your code. One of the key features that make Jest powerful is its extensive set of matchers. Matchers are functions provided by Jest that allow you to assert specific conditions in your tests. In this article, we’ll explore Jest matchers in-depth, providing clear explanations and practical examples to help you master their usage.
What are Jest Matchers?
Matchers in Jest are functions that check if a certain condition is met during the test execution. They enable you to write expressive and readable assertions, making it easier to understand the intent of your tests. Jest comes with a variety of built-in matchers that cover common use cases in testing.
Basic Matchers
Let’s start with some basic matchers that Jest provides:
1. toBe()
The toBe
matcher is used for exact equality checks. It compares values using ===
and is suitable for primitive data types.
test('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
2. toEqual()
The toEqual
matcher is used for deep equality checks. It recursively checks every field of an object or array.
test('checks if two objects are equal', () => {
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 2, a: 1 };
expect(obj1).toEqual(obj2);
});
Truthiness Matchers
Jest provides matchers for checking truthiness and falsiness:
1. toBeTruthy()
and toBeFalsy()
Use toBeTruthy
to assert that a value is truthy and toBeFalsy
for falsy values.
test('checks if a value is truthy', () => {
const result = someFunction();
expect(result).toBeTruthy();
});
Numeric Matchers
When dealing with numbers, Jest offers matchers to handle various scenarios:
1. toBeGreaterThan()
, toBeGreaterThanOrEqual()
, toBeLessThan()
, toBeLessThanOrEqual()
These matchers allow you to compare numeric values.
test('checks if a value is greater than another', () => {
const price = calculateTotalPrice();
expect(price).toBeGreaterThan(0);
});
String Matchers
Jest provides matchers for string comparisons:
1. toMatch()
Use toMatch
to check if a string matches a regular expression or includes a substring.
test('checks if a string contains a specific substring', () => {
const message = generateMessage();
expect(message).toMatch(/hello/);
});
Array Matchers
Jest includes matchers for array-related assertions:
1. toContain()
Use toContain
to check if an array contains a specific item.
test('checks if an array contains a specific item', () => {
const colors = getAvailableColors();
expect(colors).toContain('red');
});
Custom Matchers
Jest allows you to create custom matchers tailored to your specific needs. This can enhance the readability and maintainability of your tests.
expect.extend({
toBeEven(received) {
const pass = received % 2 === 0;
if (pass) {
return {
message: () => `expected ${received} not to be even`,
pass: true,
};
} else {
return {
message: () => `expected ${received} to be even`,
pass: false,
};
}
},
});
test('checks if a number is even', () => {
const number = getRandomNumber();
expect(number).toBeEven();
});
Object Matchers
toHaveProperty()
This matcher checks if an object has a specified property.
test('checks if an object has a specific property', () => {
const user = {
id: 1,
username: 'john_doe',
email: 'john@example.com',
};
expect(user).toHaveProperty('username');
});
toContainEqual()
Verifies that an array or iterable contains an expected item or subset.
test('checks if an array contains a specific subset', () => {
const users = [
{ id: 1, username: 'john_doe' },
{ id: 2, username: 'jane_doe' },
];
expect(users).toContainEqual({ id: 2, username: 'jane_doe' });
});
Function Matchers
toThrow()
Asserts that a function throws an error when called.
test('checks if a function throws an error', () => {
const faultyFunction = () => {
throw new Error('Something went wrong');
};
expect(faultyFunction).toThrow();
});
toBeCalled()
, toHaveBeenCalled()
, toHaveBeenCalledTimes()
Matchers for checking if a function or mock function has been called.
test('checks if a function has been called', () => {
const mockFunction = jest.fn();
someFunctionThatCallsMock(mockFunction);
expect(mockFunction).toBeCalled();
expect(mockFunction).toHaveBeenCalledTimes(1);
});
Promise Matchers
resolves
, rejects
These matchers are used with asynchronous code to check if a Promise resolves or rejects.
test('checks if a Promise resolves with a specific value', async () => {
const result = await asyncFunction();
expect(result).resolves.toBe('expectedValue');
});
Snapshot Matchers
toMatchSnapshot()
, toMatchInlineSnapshot()
Snapshot testing allows you to capture the output of a component or data structure and compare it to a stored snapshot.
test('captures a component snapshot', () => {
const component = render(<MyComponent />);
expect(component).toMatchSnapshot();
});
Conclusion
Jest matchers are powerful tools that make writing tests more straightforward and enjoyable and cater to various testing scenarios. By combining and customizing these matchers, you can create robust tests that cover different aspects of your code. Regularly exploring the Jest documentation and staying updated with new releases can introduce you to additional matchers and features that enhance your testing experience. Happy testing!