jQuery を使用した JavaScript コードを Jest でテストする
jQuery でごちゃごちゃやってるレガシーな感じの JavaScript コードのテストコードを書く方法
「module.exports されていない関数を Jest でテストする」の対応を行なっている前提
code:sample.js
/**
* 渡された文字列を特定のタグにセットするだけの関数
* @param {string} text セットする文字列
* @returns {undefined}
*/
function addText(text) {
$('#js-text-placeholder').text(text);
}
code:sample.html
<div id="js-text-placeholder"></div>
code:sample.test.js
global.$ = require('jquery');
// 必要なら Lodash も require する
//global._ = require('lodash');
// 今回は不要だが、テストがうまく機能しないときはアニメーションを止める
// global.$.fx.off = true;
describe('addText(text)', () => {
const addText = require('./sample.js').__get__('addText');
// !!! テスト用 HTML は += で設定すること !!!
document.documentElement.innerHTML += `
<div id="js-text-placeholder">
テスト用 HTML タグ
</div>
`;
const text = 'foo_bar_baz';
it('should add the given text to the div#js-text-placeholder tag', () => {
expect(addText(text)).toBeUndefined();
expect($('#js-text-placeholder').text()).toBe(text);
});
});
テスト用 HTML に関して
document.documentElement.innerHTML に対象 HTML からコピペで入れる
部分的なテストならこれで十分なはず
設定するときは += を使うこと
e.g. document.documentElement.innerHTML += '<div id="js-text-placeholder"></div>';
こうしないと HTML を操作する複数のテストを実行したときにうまく動かなかった
テスト中に、他のテストに document.documentElement.innerHTML をクリアされるから?
document.documentElement.innerHTML = '= だと他のテストに上書きされてテストが失敗する';
順番に実行できれば回避できるだろうが、その方法がよくわからない
テスト用 HTML に無関係の HTML が混ざってても問題ないはず
それで問題が出るなら、プログラミング設計の問題な気がする