62 lines
1.8 KiB
Markdown
62 lines
1.8 KiB
Markdown
|
---
|
||
|
title: "Suppressing logs and errors in Jest"
|
||
|
slug: /suppressing-logs-errors-jest/
|
||
|
date: 2024-09-10
|
||
|
tags: ["javascript", "unit-testing"]
|
||
|
---
|
||
|
|
||
|
It annoys me when I am working on a project and a previous developer has left
|
||
|
logs and/or thrown errors in their unit tests. To be clear: I mean when the
|
||
|
developer is testing that an error is thrown in the right circumstances, not a
|
||
|
test failure arising from regression. The former makes the latter harder to
|
||
|
detect by polluting the output.
|
||
|
|
||
|
This can be so easily prevented.
|
||
|
|
||
|
Take the following function:
|
||
|
|
||
|
```js
|
||
|
function sillyFunction(int) {
|
||
|
console.info(`Now handling ${int}`)
|
||
|
if (int > 2) throw new Error(`Error: int ${int} is greater than two`)
|
||
|
else return
|
||
|
}
|
||
|
```
|
||
|
|
||
|
To avoid pointlessly logging to the console and to confirm the error without
|
||
|
actually throwing it:
|
||
|
|
||
|
```js
|
||
|
import { jest } from "@jest/globals"
|
||
|
|
||
|
describe("sillyFunction", () => {
|
||
|
beforeEach(() => {
|
||
|
jest.spyOn(console, "info").mockImplementation(() => {})
|
||
|
})
|
||
|
|
||
|
afterEach(() => {
|
||
|
console.info.mockRestore()
|
||
|
})
|
||
|
|
||
|
it("throws error if `int` is less than 2", () => {
|
||
|
expect(() => {
|
||
|
sillyFunction(3)
|
||
|
}).toThrow("Error: int 3 is greater than two")
|
||
|
})
|
||
|
})
|
||
|
```
|
||
|
|
||
|
The `spyOn` method silences the output of `console.error` by returning nothing.
|
||
|
If we wish, we can still confirm that the log is acting as expected during the
|
||
|
runtime of the test by again using a spy:
|
||
|
|
||
|
```js
|
||
|
const consoleInfoSpy = jest.spyOn(console, "info")
|
||
|
expect(consoleInfoSpy).toHaveBeenCalledWith("Now handling x")
|
||
|
```
|
||
|
|
||
|
The `toThrow` method catches the error before it hits the console and allows us
|
||
|
to interrogate it. If it was an asynchronous function under test, we would need
|
||
|
to use the matcher `rejects.toThrow`. This waits for the promise to resolve
|
||
|
before checking if it has been rejected.
|