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


103

より良い方法があれば、私は不思議無効コンソールのエラー 内部の特定の冗談テスト(すなわち、本来のコンソールを復元し、各試験後/前)。

これが私の現在のアプローチです:

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それだけで動作するようです

ありがとう!

回答:


135

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

jest --silent

(または)

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

構成された__tests__ /setup.jsまたは jest-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"],
};

2
こんにちは!setupTestFrameworkScriptFileを優先して非推奨になりましたsetupFilesAfterEnv
elhoucine

1
モックglobal.consoleは確かに簡単な方法であり、構成された任意のを介して実行できますsetupFilesAfterEnv consoleオブジェクトのすべてのネイティブメソッドをモックすることに注意してください。そうしないと、他の予期しないエラーが発生する可能性があります。
Vadorequest

53

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

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

1
その件についての情報をありがとう。それは理にかなっています:)私はそれを復元せずに特定のテスト内でのみそのようにする方法を探していました(私は最初はそれがデフォルトの動作だと思っていました)が、beforeEachがトリックを行うと思います。
apidcloud 2017年


21

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

このやや似たアプローチは、Jest22 +でうまくいきました。

package.json

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

jest / setup.js

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

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


7

私にとって、より明確でクリーンな方法(読者は、何が起こっているのかを理解するために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;

1
また、カバー等のconsole.info、console.error、console.warnに必要
マイケルOryl

1
@ michael-liquoriなぜconsole.logを再起動する必要があるのですか?すべてのはモックがクリアされている記述の後に私は思う
Jhonatan

2
@Jhonatan確かに最近これをテストしていませんが、すべての説明の後でそれが明確になるとは思いません。よると冗談ドキュメントがありclearMocksresetMocks設定オプションは、彼らの両方のデフォルトにfalseそしてどちらもそれらのは、実際に設定しても、最初の実装を復元しますtrue。また、これはある時点で変更される可能性のある構成オプションであることを考慮すると、テストによって将来問題が発生しないように、手動でクリーンアップすることがベストプラクティスだと思います。
MichaelLiquori20年

0

別のアプローチはを使用すること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
質問の作成者は、テスト時にconsole.logを無効にする方法です。このソリューションは最適ではありません。
エリック

そこにコピーペースターの場合:交換する===!==、ニーズに応じて。私はこのアプローチを何年も使用しており、問題なく機能しますが、必要に応じて調整を行います。
ウォレスSidhrée

実際の質問には答えません。
MichaelOryl19年

これはハッキーなソリューションであり、カスタマイズすることはできません。特定のテストに対してのみ無効にし、他のテストに対して無効にしない場合はどうなりますか?
Jhonatan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.