In Jest, how can I make a test fail?

JavascriptJestjs

Javascript Problem Overview


I know I could throw an error from inside the test, but I wonder if there is something like the global fail() method provided by Jasmine?

Javascript Solutions


Solution 1 - Javascript

Jest actually uses Jasmine, so you can use fail just like before.

Sample call:

fail('it should not reach here');

Here's the definition from the TypeScript declaration file for Jest:

declare function fail(error?: any): never;

If you know a particular call should fail you can use expect.

expect(() => functionExpectedToThrow(param1)).toThrow();
// or to test a specific error use
expect(() => functionExpectedToThrow(param1)).toThrowError();

See Jest docs for details on passing in a string, regex, or an Error object to test the expected error in the toThrowError method.

For an async call use .rejects

// returning the call
return expect(asyncFunctionExpectedToThrow(param1))
  .rejects();
// or to specify the error message
// .rejects.toEqual('error message');

With async/await you need to mark the test function with async

it('should fail when calling functionX', async () => {
  await expect(asyncFunctionExpectedToThrow(param1))
    .rejects();
  // or to specify the error message
  // .rejects.toEqual('error message');
}

See documentation on .rejects and in the tutorial.

Also please note that the Jasmine fail function may be removed in a future version of Jest, see Yohan Dahmani's comment. You may start using the expect method above or do a find and replace fail with throw new Error('it should not reach here'); as mentioned in other answers. If you prefer the conciseness and readability of fail you could always create your own function if the Jasmine one gets removed from Jest.

function fail(message) {
  throw new Error(message);
}

Solution 2 - Javascript

You can do it by throwing an error. For example:

test('Obi-Wan Kenobi', () => {
  throw new Error('I have failed you, Anakin')
})

Solution 3 - Javascript

Copy/pasta failing test:

it('This test will fail', done => {
  done.fail(new Error('This is the error'))
})

Solution 4 - Javascript

Here are certain scenarios where some of the answers won't work. In a world of async-await, it is quite common to have try-catch logic like so.

try {
  await someOperation();
} catch (error) {
  expect(error.message).toBe('something');
}

Now imagine if someOperation() somehow passed, but you were expecting it to fail, then this test will still pass because it never went to the catch block. So what we want is to make sure that the test fails if someOperation does not throw an error.

So now let's see which solutions will work and which won't.

Accepted answer won't work here because the throw will be catched again.

try {
  await someOperation();
  throw new Error('I have failed you, Anakin');
} catch (error) {
  console.log('It came here, and so will pass!');
}

The answer with true === false also won't work because, assertions too throw an error like above which will be catched.

try {
  await someOperation();
  expect(true).toBe(false); // This throws an error which will be catched.
} catch (error) {
  console.log('It came here, and so will pass!');
}

The one solution that DOES WORK (as shown in @WhatWouldBeCool's answer) for this case is below. Now it explicitly fails the test.

try {
  await someOperation();
  fail('It should not have come here!')
} catch (error) {
  console.log('It never came here!');
}

Update May-2022

The fail() function is not officially supported by Jest anymore. Instead, you can do a couple of things to fail explicitly.

Method-1

You can wrap your promise function within expect and tell jest the function should reject with the given error. If the someOperation() somehow passes, jest will throw an error. If the someOperation() fails for any other reason other than the one you specified, it will throw an error. There are also different methods other than toThrowError() that you can use.

await expect(someOperation()).rejects.toThrowError('error!')
Method-2

You can declare explicitly how many assertions you expect in your test. If that doesn't match because someOperation() never failed, jest would throw an error.

expect.assertions(1)

try {
  await someOperation();
} catch (error) {
  expect(error.message).toBe('something');
}

Solution 5 - Javascript

Dont think there is, discussed here: https://github.com/facebook/jest/issues/2129

Solution 6 - Javascript

A lot of good ideas here. Only to add extra info about testing async code which may lead to trying to make Jest explicitly fail, check the docs for Testing Asynchronous Code https://jestjs.io/docs/en/asynchronous

To test a function that returns a Promise that resolves, it's important to return the Promise, so Jest knows that the test is done only when the Promise is resolved or it'll time out:

test('the data is peanut butter', () => {
  return fetchData().then(data => {
    expect(data).toBe('peanut butter')
  })
})

To test a function that returns a Promise that rejects, it's important to return the Promise, so Jest knows that the test is done only when the Promise is rejected or it'll time out. And also have to say how many assertions Jest needs to count or it won't fail if the Promise is resolved - which is wrong in this case -:

test('the fetch fails with an error', () => {
  expect.assertions(1)
  return fetchData().catch(e => expect(e).toMatch('some specific error'))
})

Solution 7 - Javascript

You can always do something like this :)

expect(true).toBe(false);

Solution 8 - Javascript

Add jest-fail-on-console npm package, then on your jest.config.js

import failOnConsole from 'jest-fail-on-console'

failOnConsole();

This will fail a test once there is a console error or warning done by jest because of an error or warning thrown in the test item.

Solution 9 - Javascript

You can throw an error simulating an error thrown by the application and then expect its message to be different from what it actually is.

        try {
            await somthingYouExpectToFail();
            throw new Error("Fail!");
        } catch (error) {
            expect(error.message).not.toBe("Fail!");
        }
    

Solution 10 - Javascript

The done callback passed to every test will throw an error if you pass a string to it.

for instance

it('should error if the promise fails', async (done) => {
try {
  const result = await randomFunction();

  expect(result).toBe(true);

  done();
} catch (e) {
  done('it should not be able to get here');
}

});

In this following code if the randomFunction throws an error it will be caught in the catch and with auto fail due to the string being passed to done.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkYuZzView Question on Stackoverflow
Solution 1 - JavascriptWhat Would Be CoolView Answer on Stackoverflow
Solution 2 - JavascriptCristóvão TrevisanView Answer on Stackoverflow
Solution 3 - JavascriptBeau SmithView Answer on Stackoverflow
Solution 4 - JavascriptRashView Answer on Stackoverflow
Solution 5 - JavascriptRikinView Answer on Stackoverflow
Solution 6 - JavascripttiomnoView Answer on Stackoverflow
Solution 7 - JavascriptÞorvaldur RúnarssonView Answer on Stackoverflow
Solution 8 - JavascriptLEMUEL ADANEView Answer on Stackoverflow
Solution 9 - JavascriptBogdanView Answer on Stackoverflow
Solution 10 - JavascriptAdearView Answer on Stackoverflow