Javascript Jest:禁用单元测试内控制台的更好方法

Javascript Jest:禁用单元测试内控制台的更好方法,javascript,unit-testing,mocking,jestjs,Javascript,Unit Testing,Mocking,Jestjs,我想知道是否有更好的方法在特定的Jest测试中禁用控制台错误(即在每次测试之前/之后恢复原始控制台) 以下是我目前的做法: describe("Some description", () => { let consoleSpy; beforeEach(() => { if (typeof consoleSpy === "function") { consoleSpy.mockRestore(); } }); test("Some tes

我想知道是否有更好的方法在特定的Jest测试中禁用控制台错误(即在每次测试之前/之后恢复原始控制台)

以下是我目前的做法:

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");
  });
});
有没有更干净的方法来完成同样的事情我想避免使用
spyOn
,但是
mockRestore
似乎只能使用它


谢谢

由于每个测试文件都在其自己的线程中运行,因此,如果要在一个文件中对所有测试禁用它,则无需还原它。出于同样的原因,你也可以直接写

console.log = jest.fn()
expect(console.log).toHaveBeenCalled();

对于特定的规范文件,Andreas的就足够了。下面的设置将抑制所有测试套件的
console.log
语句

jest --silent
(或)

要自定义
警告、信息和调试
,您可以使用下面的设置

\uuuu测试\uuuu/setup.jsjest preload.js
setupFilesAfterEnv

global.console = {
  log: jest.fn(), // console.log are ignored in tests

  // Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log`
  error: console.error,
  warn: console.warn,
  info: console.info,
  debug: console.debug,
};
jest.config.js

module.exports = {
    verbose: true,
    setupTestFrameworkScriptFile: "<rootDir>/__tests__/setup.js",
};
module.exports={
没错,
setupTestFrameworkScriptFile:“/\uuuuu测试\uuuuu/setup.js”,
};
Jest v24.x注意:setupTestFrameworkScriptFile已被弃用,取而代之的是 设置文件afterenv

module.exports={
没错,
setupFilesAfterEnv:[“/\uuuuuu测试\uuuuuu/setup.js”],
};

我发现上面的答案是:当调用任何其他
控制台
方法(例如
警告
错误
)时,在所有测试套件中抑制
控制台.log
会引发错误,因为它正在替换整个全局
控制台
对象

这种有点类似的方法在Jest 22+中适用:

package.json
使用此方法,仅模拟
console.log
,其他
console
方法不受影响。

另一种方法是使用
process.env.NODE\u env
。通过这种方式,可以有选择地选择在运行测试时显示(或不显示)什么:

这将要求将此配置放置在
package.json上:

"jest": {
  "globals": {
    "NODE_ENV": "test"
  }
}

请注意,这种方法不是对原始问题的直接解决方案,但只要有可能将
console.log
与所述条件包装在一起,就可以得到预期的结果。

对我来说,这是一种更清晰/干净的方式(读者不需要了解jest API就可以理解发生了什么),只是手动执行mockRestore的操作:

// at start of test you want to suppress
const consoleLog = console.log;
console.log = jest.fn();

// at end of test
console.log = consoleLog;

如果您只想做一个特定的测试:

beforeEach(() => {
  jest.spyOn(console, 'warn').mockImplementation(() => {});
});
beforeAll(()=>{
spyOn(控制台,'log').mockImplementation(()=>{});
spyOn(控制台,'error').mockImplementation(()=>{});
jest.spyOn(控制台,'warn').mockImplementation(()=>{});
jest.spyOn(控制台,'info').mockImplementation(()=>{});
spyOn(控制台,'debug').mockImplementation(()=>{});
});

感谢@Raja的最佳答案。下面是我正在使用的(我会注释,但不能在注释中共享多行代码块)

使用jest v26,我得到以下错误:

We detected setupFilesAfterEnv in your package.json.

Remove it from Jest configuration, and put the initialization code in src/setupTests.js:
This file will be loaded automatically.
因此,我必须从jest配置中删除
setupfileafterenv
,并将其添加到
src/setupTests.js

//https://stackoverflow.com/questions/44467657/jest-better-way-to-disable-console-inside-unit-tests
const nativeconsolererror=global.console.error
global.console.error=(…args)=>{
if(args.join(“”).includes('cannotparse CSS stylesheet')){
返回
}
返回nativeConsoleError(…args)
}

由于
jest.spyOn
对此不起作用(可能在过去),我使用了
jest.fn
手动模拟恢复,如中所述。这样,您就不应该错过任何在特定测试中根据经验不会被忽略的日志

const consoleError=console.error
在每个之前(()=>{
console.error=consoleError
})
测试('有错误',()=>{
console.error=jest.fn()
console.error('error')//看不到我
})
测试('带有错误和日志',()=>{
console.error('error')//现在您可以

})
感谢您提供有关此事的信息。这是有道理的:)我一直在寻找一种方法,只在一个特定的测试中这样做,而不必恢复它(我最初认为这是默认的行为),但我猜在每个人都这样做之前。嗨
setupTestFrameworkScriptFile
被弃用,取而代之的是
SetupFileAfterEnv
。模拟
global.console
确实是一种简单的方法,可以通过任何配置的
SetupFileAfterEnv
完成。注意模仿
控制台
对象的所有本机方法,否则可能会遇到其他意外错误。问题的作者是如何禁用console.log on测试。此解决方案不是最佳解决方案。对于复制粘贴器:将
==
替换为
==根据您的需要。我已经使用这种方法很多年了,它工作得非常完美,但我会根据自己的需要进行调整。这并不能回答实际问题。这是一个黑客解决方案,不可自定义。如果仅针对特定测试禁用,而不针对另一个测试禁用,该怎么办?您还需要涵盖console.info、console.error、console.warn等内容@michael lixori为什么需要重新启动console.log?我想在每次描述之后,嘲弄都是cleared@Jhonatan我不认为在每次描述之后它都是清晰的,尽管我最近没有测试过这一点。据介绍,有一个
clearMocks
resetMocks
配置选项,但它们都默认为
false
,即使设置为
true
,它们都不会实际恢复初始实现。而且,考虑到这是一个配置选项,可能会在某个时候更改,我认为手动清理是最好的做法,以确保您的测试在将来不会导致问题。这太棒了!它在我的测试中不起作用,我仍然有一些
控制台。在测试期间发出警告。经过多次测试,它不是bul
const logDev = msg => {
  if (process.env.NODE_ENV === 'development') {
    console.log(msg);
  }
}
logDev('Show output only while in "development" mode');
"jest": {
  "globals": {
    "NODE_ENV": "test"
  }
}
// at start of test you want to suppress
const consoleLog = console.log;
console.log = jest.fn();

// at end of test
console.log = consoleLog;
beforeEach(() => {
  jest.spyOn(console, 'warn').mockImplementation(() => {});
});
We detected setupFilesAfterEnv in your package.json.

Remove it from Jest configuration, and put the initialization code in src/setupTests.js:
This file will be loaded automatically.