DOM操作
テストが難しいとされるもう一つの関数群は、DOMを直接操作するコードです。クリックイベントをリッスンし、いくつかのデータを非同期でフェッチして、spanのコンテンツを設定する次のjQueryコードをどのようにテストできるかを見てみましょう。
displayUser.js
'use strict';
const $ = require('jquery');
const fetchCurrentUser = require('./fetchCurrentUser.js');
$('#button').click(() => {
fetchCurrentUser(user => {
const loggedText = 'Logged ' + (user.loggedIn ? 'In' : 'Out');
$('#username').text(user.fullName + ' - ' + loggedText);
});
});
ここでも、__tests__/
フォルダーにテストファイルを作成します。
__tests__/displayUser-test.js
'use strict';
jest.mock('../fetchCurrentUser');
test('displays a user after a click', () => {
// Set up our document body
document.body.innerHTML =
'<div>' +
' <span id="username" />' +
' <button id="button" />' +
'</div>';
// This module has a side-effect
require('../displayUser');
const $ = require('jquery');
const fetchCurrentUser = require('../fetchCurrentUser');
// Tell the fetchCurrentUser mock function to automatically invoke
// its callback with some data
fetchCurrentUser.mockImplementation(cb => {
cb({
fullName: 'Johnny Cash',
loggedIn: true,
});
});
// Use jquery to emulate a click on our button
$('#button').click();
// Assert that the fetchCurrentUser function was called, and that the
// #username span's inner text was updated as we'd expect it to.
expect(fetchCurrentUser).toHaveBeenCalled();
expect($('#username').text()).toBe('Johnny Cash - Logged In');
});
テストが実際のネットワークリクエストを行うのではなく、ローカルでモックデータに解決するように、fetchCurrentUser.js
をモックしています。これにより、テストが数秒ではなくミリ秒で完了し、高速なユニットテストの反復速度が保証されます。
また、テスト対象の関数は#button
DOM要素にイベントリスナーを追加するため、テストのためにDOMを正しく設定する必要があります。jsdom
とjest-environment-jsdom
パッケージは、ブラウザーにいるかのようにDOM環境をシミュレートします。これは、呼び出すすべてのDOM APIがブラウザーで観察されるのと同じように観察できることを意味します!
JSDOMのテスト環境を開始するには、jest-environment-jsdom
パッケージがまだインストールされていない場合はインストールする必要があります。
- npm
- Yarn
- pnpm
npm install --save-dev jest-environment-jsdom
yarn add --dev jest-environment-jsdom
pnpm add --save-dev jest-environment-jsdom
この例のコードは、examples/jqueryで入手できます。