Jest で DOM 操作の試験、 console.error を無視

Jest によるテストコードを書く上でいくつか嵌まったポイントをピックアップ。

DOM 操作の試験

まず引っかかったのは DOM 操作。今回はバリバリ DOM を操作したりある要素が存在しているかのチェックをする、といった完全に DOM ありきのコードを対象にしていました。

機能のユニットテストであれば直感的に分かるのですが、 DOM 操作って……。

sample/assert.js

const dom = `
<div id="hoge"></div>
`;

module.exports = dom;

sample/exception.js

const dom = `
<!--<div id="hoge"></div>-->
`;

module.exports = dom;

tests/hoge.test.js

const hoge = require('../src/hoge');
const domAssert = require('../sample/assert');
const domException = require('../sample/exception');

test('method:hoge test:assert', () => {
    document.body.innerHTML = domAssert;
    const hogeDOM = document.querySelector('#hoge');
    const hogeInstance = new hoge();
    expect(hogeInstance.judge(hogeDOM)).toBe(true);
});
test('method:hoge test:exception', () => {
    document.body.innerHTML = domException;
    const hogeDOM = document.querySelector('#hoge');
    const hogeInstance = new hoge();
    expect(hogeInstance.judge(hogeDOM)).toBe(false);
});

例えば hoge という id属性 が付与された DOM が存在するか否かのチェックをする hogeクラス に対して judge()メソッド をテストしたい場合。

  1. DOM となるHTMLタグのコードを JS の文字列としてセット
  2. それを module.exports
  3. テストコードで require() し、コード内の document.body.innerHTML へ代入する
  4. 後は通常の JS のように document.querySelector なり何なりで操作やチェックが可能。属性であれば getAttribute() してあげれば良い

……わりと素直にできることが分かりました。 Jest すごい。

The error below may be caused by using the wrong test environment

さて、上述でわりと直感的に DOM 操作した上でテストコードを記述できる、と記載しましたがいざテストをしようとすると以下のエラーが発生しました (Jest が 27系 以上)。

The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.
Consider using the “jsdom” test environment.

これは Jest に DOM 操作用の設定が必要なためのようです。

解決策としては2つ。

テストコード内に設定を記述

まずはテストコード内に設定を記述する方法。これはテストコードごとに設定を変更できる柔軟性がある一方、必要な場合は全てのテストコードで同じ記述をする必要があるため数が多いと面倒になる、というパターン。

/**
 * @jest-environment jsdom
 */

jest.config.js

もう1つは jest.config.js に記述する方法。こちらは一括指定ができるものの、テストコードごとの設定はできないので先程とは逆ですね。

module.exports = {
    testEnvironment: 'jsdom',     // 追加
    coverageDirectory: 'coverage'
};

console.error() を無視

テスト対象のコードで例外等の際に console.error() を使用していると、そのコードに入ったときに Jest が止まってしまいます。

そこで、 console.error() に遭遇しても Jest が止まらないようにする方法を。

const hoge = require('../src/hoge');
const domException = require('../sample/exception');

test('method:fuga test:exception', () => {
    jest.spyOn(console, 'error').mockImplementation((mes) => {
        console.log(mes);
    });
    document.body.innerHTML = domException;
    const hogeDOM = document.querySelector('#hoge');
    const hogeInstance = new hoge();
    expect(hogeInstance.fuga(hogeDOM)).toBe(false);
});

例えばこんな感じ。 jest.spyOn(console, 'error') ... を実際のコードを走らせる前に記述しておくことで console.error() で止まらなくなります。

参考

DOM操作

The error below may be caused by using the wrong test environment

undefined 判定

null 判定

(未使用) 非同期

console.errorで止まらないように

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。