下記の記事の続編です。
今回は、ESModule(Import / Export)を使ってJSファイルをテストしてみます。
@jest/globalsをインストール
npm i @jest/globals
eslintインストール
必須ではないですが、eslintもインストールしましょう。
npm i eslint
package.jsonの修正
下記のように修正します。
"type": "module"を追加するだけです。
package.json
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "jest"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^9.39.2",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0"
},
"jest": {
"testEnvironment": "jsdom"
},
"dependencies": {
"@jest/globals": "^30.2.0"
}
}
実装
frontend/src/fruits.js
export async function loadFruits(){
return fetch('/api/fruits')
.then(response => response.json())
.then(data =>{
const ul = document.getElementById('fruit-list');
data.forEach(item =>{
const li = document.createElement('li');
li.textContent = item;
ul.appendChild(li);
})
})
.catch(error =>{
console.log('エラー:', error);
})
}
テストコード
frontend/tests/fruits.test.js
//ESModule版テストコード
import { describe, test, expect, jest, beforeEach } from '@jest/globals';
import { loadFruits } from '../src/fruits';
// fetch をモック
global.fetch = jest.fn();
describe('loadFruits', () => {
beforeEach(() => {
// DOMを初期化
document.body.innerHTML = `
<ul id="fruit-list"></ul>
`;
fetch.mockClear();
});
test('Controllerから取得した果物が画面に表示される', async () => {
// Spring Boot Controller の返却値を模擬
fetch.mockResolvedValue({
json: () => Promise.resolve(['Apple', 'Banana', 'Orange'])
});
await loadFruits();
const liList = document.querySelectorAll('#fruit-list li');
expect(liList.length).toBe(3);
expect(liList[0].textContent).toBe('Apple');
expect(liList[1].textContent).toBe('Banana');
expect(liList[2].textContent).toBe('Orange');
});
});
package.json
{
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
},
"devDependencies": {
"jest": "^29.0.0",
"jest-environment-jsdom": "^29.0.0"
},
"jest": {
"testEnvironment": "jsdom"
}
}
Node.jsが格納されているフォルダの上で右クリック⇒[コマンドプロンプト]を選択します。

コンソールコマンドで下記のコマンドを入力します。
node --experimental-vm-modules node_modules/jest/bin/jest.js
これで、testsフォルダ配下のjSファイルがテストされます。
特定のファイルのみテストしたい場合
もし、特定のファイルのみテストしたい場合は下記のようにします。
node --experimental-vm-modules node_modules/jest/bin/jest.js frontend/tests/<ファイル名>
HTMLレポート出力したい場合
node --experimental-vm-modules node_modules/jest/bin/jest.js frontend/tests/<ファイル名> --coverage --coverageReporters=html
package.json に設定する場合
package.json
{
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --coverageReporters=html"
}
}
これで:
npm test
を実行すると HTML レポートも作成されます。
おまけ
ES Modules を使わず CommonJS に統一する方法
① テスト対象JSを修正
frontend/src/fruits.js
frontend/src/fruits.js
function loadFruits() {
return fetch('/api/fruits')
.then(response => response.json())
.then(data => {
const ul = document.getElementById('fruit-list');
data.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
ul.appendChild(li);
});
})
.catch(error => {
console.error('エラー:', error);
});
}
module.exports = { loadFruits };
② テストコードを修正
frontend/tests/fruits.test.js
frontend/tests/fruits.test.js
const { loadFruits } = require('../src/fruits');
// fetch をモック
global.fetch = jest.fn();
describe('loadFruits', () => {
beforeEach(() => {
document.body.innerHTML = `
<ul id="fruit-list"></ul>
`;
fetch.mockClear();
});
test('Controllerから取得した果物が画面に表示される', async () => {
fetch.mockResolvedValue({
json: () => Promise.resolve(['Apple', 'Banana', 'Orange'])
});
await loadFruits();
const liList = document.querySelectorAll('#fruit-list li');
expect(liList.length).toBe(3);
expect(liList[0].textContent).toBe('Apple');
expect(liList[1].textContent).toBe('Banana');
expect(liList[2].textContent).toBe('Orange');
});
});
デフォルトの仕組み
Jest:CommonJS 前提
Node.js:CommonJS がデフォルト
import/export:ES Modules
【HTML5】WebSocketとJavaサンプルプログラムのご紹介