web-dev-qa-db-ja.com

Jest:ユニットテスト内のコンソールを無効にするより良い方法

コンソールエラーを無効にするinsidea 特定の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はそれでのみ動作するようだ

ありがとう!

39
Apidcloud

特定のspecファイルについては、Andreasのもので十分です。以下の設定では、すべてのテストスイートのconsole.logステートメントが抑制されますが、

jest --silent

(または)

warn, info and debugをカスタマイズするには、以下のセットアップを使用できます

__ tests __/setup.jsorjest-preload.jssetupFilesAfterEnvで設定

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",
};

Jest v24.x注:setupTestFrameworkScriptFileは廃止され、setupFilesAfterEnvが採用されました。

module.exports = {
    verbose: true,
    setupFilesAfterEnv: ["<rootDir>/__tests__/setup.js"],
};
40
Raja Jaganathan

すべてのテストファイルは独自のスレッドで実行されるため、1つのファイル内のすべてのテストに対して無効にする場合、ファイルを復元する必要はありません。同じ理由で、あなたも書くことができます

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

上記の答えは、すべてのテストスイートでconsole.logを抑制すると、他のconsoleメソッド(たとえばwarnerror)が置き換えられてから呼び出されたときにエラーがスローされることがわかりました。グローバルconsoleオブジェクト全体。

このやや似たアプローチが、Jest 22+で機能しました。

package.json

"jest": {
  "setupFiles": [...],
  "setupTestFrameworkScriptFile": "<rootDir>/jest/setup.js",
  ...
}

jest/setup.js

jest.spyOn(global.console, 'log').mockImplementation(() => jest.fn());

このメソッドを使用すると、console.logのみがモックされ、他のconsoleメソッドは影響を受けません。

13
nickb

私にとって、より明確でクリーンな方法(読者は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;
4
Michael Liquori

別のアプローチは、process.env.NODE_ENVを使用することです。 この方法により、テストの実行中に表示する(または表示しない)ものを選択できます

if (process.env.NODE_ENV === 'development') {
  console.log('Show output only while in "development" mode');
} else if (process.env.NODE_ENV === 'test') {
  console.log('Show output only while in "test" mode');
}

または

const logDev = msg => {
  if (process.env.NODE_ENV === 'development') {
    console.log(msg);
  }
}
logDev('Show output only while in "development" mode');

これには、この構成をpackage.jsonに配置する必要があります。

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

このアプローチは元の質問の直接的な解決策ではありませんが、console.logを前述の条件でラップする可能性がある限り、期待される結果が得られることに注意してください。

1