Skip to content

Instantly share code, notes, and snippets.

@agwells
Last active January 9, 2022 18:45
Show Gist options
  • Save agwells/b8f0ed590eaad5e901b028bd10416d2e to your computer and use it in GitHub Desktop.
Save agwells/b8f0ed590eaad5e901b028bd10416d2e to your computer and use it in GitHub Desktop.
Programmatically fail a Jest test
/**
* Sometimes you want to programmatically force a Jest test failure. For example, mocking "console.warn()" to
* make tests fail if they print warning messages to the console. Throwing an error isn't sufficient, because
* the calling code may be in a try/catch block.
*
* Jest has no "fail()" method** to automatically trigger a test failure, but you can do it with an "expect()" matcher
* that will always fail, such as "expect(true).toBe(false)". This will fail the test, but the output isn't very
* self-explanatory. You can improve on it by providing a message string as one of the arguments:
* "expect(null).toBe('Automatic Failure!')". This is better, but the output is still a little confusing, saying
* it expected "null" and received "Automatic Failure!"
*
* So, to get a more descriptive error message, you need to write a custom matcher, like this one. It doesn't run
* any tests, just fails, and prints the provided message.
*
* expect().alwaysFail("Automatic Failure!");
*
* Anything provided in the "expect()" will be printed as "Details", which is useful in the previously-mentioned
* case of failing on console messages. Your mock console functions can pass the args they received into "expect()",
* and it will show them in the failure output.
*
* **Footnote: Okay, Jest is actually using a fork of Jasmine under the hood, and Jasmine does have a global
* "fail()" method, which works just fine in Jest tests! See https://jasmine.github.io/api/2.9/global.html#fail
* But that's a non-documented feature, which I wouldn't want to rely on. Also, the messages printed with fail()
* aren't formatted as nicely as Jest matcher failure messages.
*/
expect.extend({
alwaysFail(received, failureMessage) {
return {
pass: false,
message: () =>
failureMessage +
(received ? '\n\nDetails:\n' + this.utils.printReceived(received) : ''),
};
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment