Register to get access to free programming courses with interactive exercises

Error testing JS: Advanced Testing

The main tests to write are tests for properly working code. But in some situations, the code has to return errors, and these too may need to be checked. Errors are situations where the code throws an exception. What features do they have? Look at this test:

test('boom!', () => {
  try {
    functionWithException(0);
  } catch (e) {
    expect(e).not.toBeNull();
  }
});

This code is trying to test a situation where functionWithException() throws an exception if you pass it 0. Do you think this test will verify that the function actually generates an exception?

The correct answer is no. If functionWithException() doesn't throw an exception, the test passes because the code doesn't get into the catch block.

Jest's documentation offers its own way of testing such situations. Jest allows you to specify the number of statements to be executed in the test. If this doesn't happen, Jest reports an error:

test('boom!', () => {
  // Number of statements to be run in this test
  expect.assertions(1);

  try {
    functionWithException(0);
  } catch (e) {
    expect(e).not.toBeNull();
  }
});

This method is extremely dangerous. It generates flimsy tests that are tied to the way they are written. If you want to add a new statement, the test will fail, and you'll have to modify it. You will always have to make sure that this number is correct. Don't use this approach, the more contextual dependencies there are, the harder it is to figure out the code, and the easier it is to make mistakes.

And now we'll get to the proper way. Jest has a matcher that independently catches the exception and checks that it was actually generated.

test('boom!', () => {
  expect(() => {
    functionWithException(0);
  }).toThrow();
});

The main feature of this matcher is that it takes a function that's called internally as input. Thanks to this, it can independently track when the exception appears. This code contains no implicit state and no unnecessary checks. It does exactly what needs to be done and doesn't require too much from us. Moreover, it's theoretically possible to have a test in which several checks for various exceptions are made at once. This is much harder to pull off with the previous methods.

Sometimes, it's important not just to catch an exception, but also to make sure that it's an expected exception. This can be done by passing a string that must be present in the exception message to the toThrow() matcher, so you can check that the error message appears.

test('boom!', () => {
  expect(() => {
    functionWithException(0);
  }).toThrow('divide by zero');
});

Recommended materials

  1. Error Snapshots

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.