jest"> jest"> Mongoose で Jest を使用したテスト

Jest は通常テストに使用され、Facebook によって開発された JavaScript ランタイムです。Jest は主に React アプリケーションのテスト用に設計されているため、それを Node.js サーバーサイドアプリケーションのテストに使用すると、多くの注意事項が生じます。Mocha など、別のテストフレームワークの使用を強く推奨します。

Mongoose からの Jest 警告を抑制するには、SUPPRESS_JEST_WARNINGS 環境変数を設定します。

env SUPPRESS_JEST_WARNINGS=1 npm test

危険な領域に足を踏み入れて Jest で Mongoose アプリをテストする場合は、以下の情報を確認してください。

Jest <=26 を使用している場合、Mongoose アプリをテストするときに Jest のデフォルトの jsdom test environment を使用しないでください(Mongoose のブラウザライブラリ のみを使用するアプリケーションを明示的にテストしている場合を除く)。Jest >=27 では "node" が Jest のデフォルトの testEnvironment になるため、この問題は発生しなくなりました。

jsdom test environment は Node.js でブラウザのようなテスト環境を作成しようとするものであり、スタブされた setTimeout() 関数 がテスト後にサイレントに失敗するなど、多くの厄介な問題が発生します。Mongoose は一般的に jsdom をサポートしておらず、jsdom test environment で正しく機能することが期待されていません。

testEnvironment を Node.js に変更するには、jest.config.js ファイルに testEnvironment を追加します。

module.exports = {
  testEnvironment: 'node'
};

タイマーモック

Mongoose アプリをテストするときは、絶対に タイマーモック を使用しないでください。これは Jest >=25 を使用している場合は特に重要で、これは process.nextTick() をスタブします。

フェイクタイマーは setTimeout()setInterval() などのグローバル関数をスタブし、基盤となるライブラリでこれらの関数が使用されている場合に問題が発生します。Mongoose と MongoDB Node.js ドライバーは、イベントループの次のティックまで作業を延期したり、MongoDB サーバーへの接続を監視したりするために、これらの関数を使用します。

どうしてもタイマーモックを使用する場合は、useFakeTimers() の呼び出し前に Mongoose をインポートしてください。

// Fine for basic cases, but may still cause issues:
const mongoose = require('mongoose');

jest.useFakeTimers();

// Bad:
jest.useFakeTimers();

const mongoose = require('mongoose');

Mongoose の開発者はすでに setImmediate() を使用してイベントループの次のティックまで作業を延期しない コードをリファクタリングしていますが、Mongoose が依存しているすべてのライブラリが setImmediate() を使用していないことを完全に保証することはできません。

より良い方法は、setTimeout() を囲む独自のラッパーを作成し、代わりに sinon を使用してそれをスタブすることです。

// time.js
exports.setTimeout = function() {
  return global.setTimeout.apply(global, arguments);
};

// Tests
const time = require('../util/time');
const sinon = require('sinon');
sinon.stub(time, 'setTimeout');

globalSetupglobalTeardown

mongoose.connect() または mongoose.createConnection() を呼び出すために globalSetup を使用しないでください。Jest は globalSetup を別の環境で実行するため、テストで globalSetup で作成した接続を使用することはできません。

詳細情報

Mongoose アプリを正しくテストする方法を学びたいですか?Pluralsight の Node.js と Express を使用した RESTful Web サービス コースには、Mongoose アプリを Mocha でテストする方法に関する素晴らしいセクションがあります。

RESTful Web Services with Node.js and Express