JSDOM で Enzyme を使用する

JSDOM は、現実的なテスト環境を作成するために使用できる、JavaScript ベースのヘッドレスブラウザです。

Enzyme の mount API は DOM を必要とするため、ブラウザ環境以外(つまり、Node 環境)で mount を使用する場合は、JSDOM が必要です。

Enzyme を最適に使用するには、React を初めて読み込む *前* にグローバルスコープにドキュメントを読み込むことをお勧めします。以下のスクリプトは、React のコードが実行される *前* に実行されることが非常に重要です。

その結果、下記のようなスタンドアロンのスクリプトが一般的に良いアプローチです。

jsdom v10〜:

/* setup.js */

const { JSDOM } = require('jsdom');

const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  Object.defineProperties(target, {
    ...Object.getOwnPropertyDescriptors(src),
    ...Object.getOwnPropertyDescriptors(target),
  });
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
global.requestAnimationFrame = function (callback) {
  return setTimeout(callback, 0);
};
global.cancelAnimationFrame = function (id) {
  clearTimeout(id);
};
copyProps(window, global);

jsdom 旧API のサンプルもここにあります。

jsdom ~<v10:

/* setup.js */

const { jsdom } = require('jsdom');

global.document = jsdom('');
global.window = document.defaultView;
global.navigator = {
  userAgent: 'node.js',
};

function copyProps(src, target) {
  const props = Object.getOwnPropertyNames(src)
    .filter((prop) => typeof target[prop] === 'undefined')
    .reduce((result, prop) => ({
      ...result,
      [prop]: Object.getOwnPropertyDescriptor(src, prop),
    }), {});
  Object.defineProperties(target, props);
}
copyProps(document.defaultView, global);

describeWithDOM API とテスト後のドキュメントのクリア

以前のバージョンの Enzyme には、公開されている describeWithDOM API があり、これは各テストの前に新しい JSDOM ドキュメントをグローバル名前空間に読み込み、テストが決定論的で副作用がないことを保証していました。

このアプローチはもはや推奨されていません。React のソースコードは、実行されている環境についていくつかの仮定を行い、その1つは、「require 時」に見つかった global.document が、それが心配する必要がある唯一のドキュメントであるということです。その結果、この種の「再読み込み」は、防止するよりも多くの問題を引き起こします。

ただし、グローバルDOM API を使用するテストに、他のテストの結果を変える可能性のあるリークした副作用がないことを確認することが重要です。より良い選択肢があるまで、これはユーザーの責任となります。

JSDOM + Mocha

JSDOM でテストを行う場合、上記の setup.js ファイルはテストスイートを実行する前に実行する必要があります。Mocha を使用している場合、これはコマンドラインで --require オプションを使用して行うことができます。

mocha --require setup.js --recursive path/to/test/dir

Node.jsとの互換性

Jsdom は Node 4 以上が必要です。そのため、mount と共に使用したい場合は、マシンに Node 4 または iojs がインストールされていることを確認する必要があります。古いバージョンの Node を使用している場合は、Karma などのブラウザベースのテストランナーの使用を試すことができます。

Node バージョンの切り替え

場合によっては、異なるバージョンの Node を切り替える必要がある場合があります。nvm という CLI ツールを使用すると、Node のバージョンをすばやく切り替えることができます。

nvm をインストールするには、http://nvm.sh から curl スクリプトを使用し、その後

nvm install 4

これで、マシンは Node 4 を実行するようになります。nvm use コマンドを使用して、2つの環境間を切り替えることができます。

nvm use 0.12
nvm use 4