Register to get access to free programming courses with interactive exercises

Matchers (expect) JS: Automated testing

There are several popular ways to write asserts. Besides calling functions, people also like to use matchers, which bear certain similarities to a mini-language to write checks.

Matchers became popular in test frameworks after the emergence of BDD) (Behaviour Driven Development). Technically, this approach tends to make tests look like a natural language description of the task at hand. This makes it possible to use them as documentation for people who can't read program code (anyway, in practice, it's a bit more complicated). Matchers have replaced the usual function statements in many languages:

// Checking reference equality
// assert.equal([1, 2], [1, 2])
expect([1, 2]).toBe([1, 2]); // false

// Checking value equality
// assert.deepEqual([1, 2], [1, 2])
expect([1, 2]).toEqual([1, 2]); // true

Any matcher in Jest starts with the expect(data) function, which takes the data for checking. Then, expect() returns a special object, on which you can call various matchers to check. Jest has dozens of matchers for a wide variety of situations. Their number is so large since developers want to have the most accurate possible account of why what happened.

Let's imagine a function that returns an array, and we want to check its size. To do this, you can use the toBe matcher:

const data = [1, 2, 3];
// take takes the first n elements
// assert.equal(take(data, 2).length, 2)
expect(take(data, 1).length).toBe(2);

This matcher will do the job just fine. But if an error occurs, the output is not very informative:

expect(received).toBe(expected) // Object.is equality

Expected: 2
Received: 1

Therefore, it's better to take a specialized matcher to check the size of the array:

expect(take(data, 1)).toHaveLength(2);

Then the output will tell us much more:

expect(received).toHaveLength(expected)

Expected length: 2
Received length: 1
Received array:  [1]

Because expect passes the array itself, not its length, Jest can output the contents of the array if an error occurs. This, again, makes debugging easier.

Below are some popular matchers that are useful in everyday testing:

expect(null).toBeNull();

// Checks a value to see if it is truthy (a truthy value is any value that is considered to be true)
expect(true).toBeTruthy();
// Exact comparison with true
expect(true).toBe(true);

expect(undefined).toBeUndefined();

// Check if an array contains an element
expect([1, 2, 3]).toContain(2);

// Checking if a string contains a substring
expect('hello, world').toMatch('hello');

// Checks if an object has a property with a certain value
expect({ key: 'value' }).toHaveProperty('key', 'value');

In addition, you can apply the not modifier to any matcher, which will invert the matcher's behavior:

expect(null).not.toBeNull(); // not null
expect(undefined).not.toBeUndefined(); // not undefined
expect([1, 2, 3]).not.toContain(2); // not contain 2
expect('hello, world').not.toMatch('hello'); // not match hello

https://repl.it/@hexlet/js-testing-matchers-expect-en#index.test.js

The toMatchObject matcher is particularly worth noting. It's used when we're not interested in the whole object, only part of it:

const user = {
  firstName: 'john',
  lastName: 'smith',
  age: '33',
};

// the test is successful, since only firstName is checked
expect(user).toMatchObject({ firstName: 'john' });

These aren't all the matchmakers that Jest has. Moreover, Jest is flexible enough to allow you to add more matchers. You can find libraries with matchers for different situations on GitHub.

In general, you'll have to keep looking at the documentation to remember what's there. Otherwise, it might come down to using to Equal() only. Perhaps this is the main disadvantage of using matchers: you need to remember them and apply them correctly.


Recommended materials

  1. Jest Matchers

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

Bookmate
Health Samurai
Dualboot
ABBYY
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.