Jest: Better way to disable console inside unit tests

100,874

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;
Share:
100,874

Related videos on Youtube

Apidcloud
Author by

Apidcloud

Updated on July 08, 2022

Comments

  • Apidcloud
    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, but mockRestore only seems to work with it.

    Thanks!

    • Devin Rhode
      Devin Rhode almost 3 years
      I 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
      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
    Apidcloud about 7 years
    Thank 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
    elhoucine over 5 years
    Hi! setupTestFrameworkScriptFile is deprecated in favor of setupFilesAfterEnv.
  • Vadorequest
    Vadorequest almost 5 years
    Mocking global.console is indeed a simple way to go, and can be done through any configured setupFilesAfterEnv . Beware to mock all native methods of the console object or you may encounter other unexpected errors.
  • Erick
    Erick over 4 years
    What the author of the question is how to disable console.log on testing. This solution is not optimal.
  • Wallace Sidhrée
    Wallace Sidhrée over 4 years
    For 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
    Michael Oryl over 4 years
    Doesn't answer the actual question.
  • Michael Oryl
    Michael Oryl over 4 years
    You also need to cover console.info, console.error, console.warn, etc.
  • sheriff_paul
    sheriff_paul over 4 years
    this is brilliant!
  • Jhonatan
    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
    Jhonatan almost 4 years
    This is a hacky solution and not customizable. What if disable only for a specific test and not the other one?
  • Michael Liquori
    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 and resetMocks configuration option but they both default to false, and neither of those actually restore the initial implementation even if set to true. 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
    Dimitri Kopriwa over 3 years
    It doesn't work in my tests, I still have some console.warn during test. Tested multiple times, it's not bulletproof
  • user115014
    user115014 over 3 years
    Noice Toit Smort!
  • Brian Ho
    Brian Ho over 3 years
    This is a good solution. It allows me to continue looking at other console.warn (or console.log) for debugging.
  • adi518
    adi518 about 3 years
    It doesn't work. It may have worked in the past, but now it's broken.
  • jgreen
    jgreen about 3 years
    It 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
    Peter Gerdes about 3 years
    For 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
    Peter Gerdes about 3 years
    Note 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
    fenix.shadow almost 3 years
    I 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
    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 an it. 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
    Ariane over 2 years
    But the next tests in the same file will still have it mocked, right? Depending on the situation, that may not be ideal.
  • Finesse
    Finesse over 2 years
    You can also add the "silent": true option to the jest.config.js file
  • Erik Hermansen
    Erik Hermansen over 2 years
    The 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
    Constantin over 2 years
    Spies are isolated per test
  • Wolfgang
    Wolfgang over 2 years
    This one worked
  • codeepic
    codeepic about 2 years
    Awesome little helper! Thanks for that!!!