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

Api*_*oud 44 javascript unit-testing mocking jestjs

我不知道是否有更好的方法来禁用错误控制台 里面一个特定的玩笑测试(即,恢复原来的控制台前/每次测试后).

这是我目前的做法:

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");
  });
});
Run Code Online (Sandbox Code Playgroud)

是否有更简洁的方法来完成同样的事情?我想避免spyOn,但mockRestore似乎只能使用它.

谢谢!

Con*_*tin 88

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

beforeEach(() => {
  jest.spyOn(console, 'warn').mockImplementation(() => {});
});
Run Code Online (Sandbox Code Playgroud)

  • 它在我的测试中不起作用,我在测试期间仍然有一些“console.warn”。经过多次测试,它不是防弹的 (8认同)
  • @fenix.shadow 它很容易适应在单个测试中执行此操作。任何可以在“beforeEach”中完成的事情都可以在“it”中完成。至于人们说这不起作用……对我来说却有用。您可能还想捕获 Vue Test Utils 的默认错误处理程序抛出的错误。 (8认同)
  • 我不知道为什么这个答案有这么多人点赞。这是在每次测试之前禁用控制台功能的好方法(正如名称“beforeEach”所暗示的那样),但它并没有回答OP的问题,即“如何在特定的Jest测试中禁用控制台错误”。 (6认同)
  • 将其调整为在单个测试中使用的缺失部分是随后调用“consoleSpy.mockRestore()”。此解决方案中给出的代码将为 JS 文件中随后执行的所有测试禁用控制台日志记录,这可以隐藏错误。OP 的原始代码示例修复了这个问题。 (4认同)
  • 这太棒了! (2认同)

Raj*_*han 54

对于特定的spec文件,Andreas的足够好.以下设置将禁止console.log所有测试套件的语句,

jest --silent
Run Code Online (Sandbox Code Playgroud)

(要么)

要自定义,warn, info and debug您可以使用以下设置

__tests __/setup.js

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,
};
Run Code Online (Sandbox Code Playgroud)

jest.config.js

module.exports = {
    verbose: true,
    setupTestFrameworkScriptFile: "<rootDir>/__tests__/setup.js",
};
Run Code Online (Sandbox Code Playgroud)

  • 嗨!不赞成使用setupTestFrameworkScriptFile,而建议使用setupFilesAfterEnv。 (2认同)
  • 模拟 `global.console` 确实是一个简单的方法,可以通过任何配置的 `setupFilesAfterEnv` 来完成。请注意模拟“console”对象的所有本机方法,否则您可能会遇到其他意外错误。 (2认同)
  • 您还可以将 `"silent": true` 选项添加到 `jest.config.js` 文件中 (2认同)

And*_*rle 35

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

console.log = jest.fn()
expect(console.log).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)

  • 感谢您提供有关此事的信息。它确实有道理:)我一直在寻找一种方法,使其仅在特定测试中实现这种方式,而不必恢复它(我最初认为这是默认行为),但我想 beforeEach 可以解决这个问题。 (2认同)

nic*_*ckb 14

我发现上面的答案是:console.log在调用任何其他console方法(例如)时,所有测试套件中的压缩都会引发错误warn,error因为它正在替换整个全局console对象.

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

的package.json

"jest": {
  "setupFiles": [...],
  "setupTestFrameworkScriptFile": "<rootDir>/jest/setup.js",
  ...
}
Run Code Online (Sandbox Code Playgroud)

开玩笑/ setup.js

jest.spyOn(global.console, 'log').mockImplementation(() => jest.fn());
Run Code Online (Sandbox Code Playgroud)

使用此方法,仅console.log模拟并且其他console方法不受影响.


Dmi*_*nko 9

beforeAll(() => {
    jest.spyOn(console, 'log').mockImplementation(() => {});
    jest.spyOn(console, 'error').mockImplementation(() => {});
    jest.spyOn(console, 'warn').mockImplementation(() => {});
    jest.spyOn(console, 'info').mockImplementation(() => {});
    jest.spyOn(console, 'debug').mockImplementation(() => {});
});
Run Code Online (Sandbox Code Playgroud)


Mic*_*ori 8

对我来说,一个更清晰/干净的方法(读者需要很少的 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;
Run Code Online (Sandbox Code Playgroud)

  • @Jhonatan,我认为每次描述后都不清楚,尽管我最近没有测试过这一点。根据[jest docs](https://jestjs.io/docs/en/configuration.html#resetmocks-boolean),有一个“clearMocks”和“resetMocks”配置选项,但它们都默认为“false”,**并且**即使设置为“true”,这些都不会真正恢复初始实现。而且,考虑到这是一个可以在某些时候更改的配置选项,我认为最好的做法是手动清理以确保您的测试将来不会引起问题。 (2认同)

Tha*_*P A 5

如果您使用命令npm test来运行测试,请更改package.jsontest script中的内容,如下所示

{
  ....
  "name": "....",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest --silent",         // add --silent to jest in script like this
    "lint": "eslint ."
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

或者您可以直接运行命令npx jest --silent来清除测试时的所有日志和错误


Dr-*_*ket 5

这是您可能想要使用的所有行。您可以将它们直接放入测试中:

jest.spyOn(console, 'warn').mockImplementation(() => {});
console.warn("You won't see me!")
expect(console.warn).toHaveBeenCalled();
console.warn.mockRestore();
Run Code Online (Sandbox Code Playgroud)