Jest: Better way to disable console inside unit tests
Solution 1
For particular spec file, Andreas's is good enough. Below setup will suppress console.log
statements for all test suites,
jest --silent
(or)
To customize warn, info and debug
you can use below setup
tests/setup.js or jest-preload.js configured in setupFilesAfterEnv
global.console = {
...console,
// uncomment to ignore a specific log level
log: jest.fn(),
debug: jest.fn(),
info: jest.fn(),
// warn: jest.fn(),
// error: jest.fn(),
};
jest.config.js
module.exports = {
verbose: true,
setupFilesAfterEnv: ["<rootDir>/__tests__/setup.js"],
};
Solution 2
If you want to do it just for a specific test:
beforeEach(() => {
jest.spyOn(console, 'warn').mockImplementation(() => {});
});
Solution 3
As every test file runs in its own thread there is no need to restore it if you want to disable it for all test in one file. For the same reason you can also just write
console.log = jest.fn()
expect(console.log).toHaveBeenCalled();
Solution 4
I found that the answer above re: suppressing console.log
across all test suites threw errors when any other console
methods (e.g. warn
, error
) were called since it was replacing the entire global console
object.
This somewhat similar approach worked for me with Jest 22+:
package.json
"jest": {
"setupFiles": [...],
"setupTestFrameworkScriptFile": "<rootDir>/jest/setup.js",
...
}
jest/setup.js
jest.spyOn(global.console, 'log').mockImplementation(() => jest.fn());
Using this method, only console.log
is mocked and other console
methods are unaffected.
Solution 5
To me a more clear/clean way (reader needs little knowledge of the jest API to understand what is happening), is to just manually do what mockRestore does:
// at start of test you want to suppress
const consoleLog = console.log;
console.log = jest.fn();
// at end of test
console.log = consoleLog;
Related videos on Youtube
Apidcloud
Updated on July 08, 2022Comments
-
Apidcloud almost 2 years
I wonder if there is a better way to disable console errors inside a specific Jest test (i.e., restore the original console before/after each test).
Here is my current approach:
describe("Some description", () => { let consoleSpy; beforeEach(() => { if (typeof consoleSpy === "function") { consoleSpy.mockRestore(); } }); test("Some test that should not output errors to jest console", () => { expect.assertions(2); consoleSpy = jest.spyOn(console, "error").mockImplementation(); // some function that uses console error expect(someFunction).toBe("X"); expect(consoleSpy).toHaveBeenCalled(); }); test("Test that has console available", () => { // shows up during jest watch test, just as intended console.error("test"); }); });
Is there a cleaner way of accomplishing the same thing? I would like to avoid
spyOn
, butmockRestore
only seems to work with it.Thanks!
-
Devin Rhode almost 3 yearsI accidentally ended up hiding a real error doing this. Ideally, first thing you should try to do is diagnose a warning or error. If it's truly benign, there are plenty of answers below to help in hiding it.
-
Erik Hermansen over 2 years@DevinRhode, it's decent advice But there are cases where console output is expected as part of a test, e.g. testing the error-handling code in a function. And sometimes you may want to call 3rd-party code that console logs, rather than mocking it out.
-
-
Apidcloud about 7 yearsThank you for the info on that matter. It does make sense :) I was looking for a way to make it that way only inside a specific test without having to restore it (I initially thought that was the behaviour by default), but I guess beforeEach does the trick.
-
elhoucine over 5 yearsHi!
setupTestFrameworkScriptFile
is deprecated in favor ofsetupFilesAfterEnv
. -
Vadorequest almost 5 yearsMocking
global.console
is indeed a simple way to go, and can be done through any configuredsetupFilesAfterEnv
. Beware to mock all native methods of theconsole
object or you may encounter other unexpected errors. -
Erick over 4 yearsWhat the author of the question is how to disable console.log on testing. This solution is not optimal.
-
Wallace Sidhrée over 4 yearsFor copy-pasters out there: replace
===
with!==
according to your needs. I've been using this approach for years and it works flawlessly, but I do make adjustments according to my needs. -
Michael Oryl over 4 yearsDoesn't answer the actual question.
-
Michael Oryl over 4 yearsYou also need to cover console.info, console.error, console.warn, etc.
-
sheriff_paul over 4 yearsthis is brilliant!
-
Jhonatan almost 4 years@michael-liquori why do you need to restart the console.log? I think after every describe the mocks are cleared
-
Jhonatan almost 4 yearsThis is a hacky solution and not customizable. What if disable only for a specific test and not the other one?
-
Michael Liquori almost 4 years@Jhonatan I don't think it does clear after every describe, though I haven't tested this recently to be sure. According to jest docs there is a
clearMocks
andresetMocks
configuration option but they both default tofalse
, and neither of those actually restore the initial implementation even if set totrue
. And, considering this is a config option that could be changed at some point, I think it is best practice to clean up manually to ensure your tests won't cause problems in the future. -
Dimitri Kopriwa over 3 yearsIt doesn't work in my tests, I still have some
console.warn
during test. Tested multiple times, it's not bulletproof -
user115014 over 3 yearsNoice Toit Smort!
-
Brian Ho over 3 yearsThis is a good solution. It allows me to continue looking at other console.warn (or console.log) for debugging.
-
adi518 about 3 yearsIt doesn't work. It may have worked in the past, but now it's broken.
-
jgreen about 3 yearsIt works, though perhaps not as you want depending on where you put the statements (see jestjs.io/docs/…). Once this runs, it will stay that way for the rest of the test run since console is a global object. (Node v16.0.0. Jest 24.9.0).
-
Peter Gerdes about 3 yearsFor me this creates a mock that I can check has been called the appropriate number of times but doesn't suppress the resulting message. To do that I had to overload the global object in my setup.
-
Peter Gerdes about 3 yearsNote that if you then want to check on the mock (or clear it) you will need to refer to it as console.log, e.g., expect(console.log).toBeCalledTimes(1).
-
fenix.shadow almost 3 yearsI don't know why this answer has so many upvotes. It's a great way to disable console functionality before each test (as the name
beforeEach
would imply), but it doesn't answer the OP's question, which is "how to disable console errors inside a specific Jest test". -
Ariane over 2 years@fenix.shadow it's very easily adaptable to doing it inside a single test. Anything that can be done within a
beforeEach
can be done within anit
. As for people saying it doesn't work... it does for me. You may want to also catch the error thrown by Vue Test Utils's default error handler. -
Ariane over 2 yearsBut the next tests in the same file will still have it mocked, right? Depending on the situation, that may not be ideal.
-
Finesse over 2 yearsYou can also add the
"silent": true
option to thejest.config.js
file -
Erik Hermansen over 2 yearsThe missing part of adapting it to be used in a single test is calling
consoleSpy.mockRestore()
afterward. The code given in this solution will leave console logging disabled for all tests in the JS file that are executed afterward which can hide errors. The OP's original code sample fixes this. -
Constantin over 2 yearsSpies are isolated per test
-
Wolfgang over 2 yearsThis one worked
-
codeepic about 2 yearsAwesome little helper! Thanks for that!!!