JestでESModulesをテストする
JestでESModulesをテストする方法を調べましたのでまとめます。
Jestのgetting-startedに載っている2つの数値を加算する関数
を、mjs
, mts
で記述し、テストします。
今回作成したファイルはGitHubで公開していますので、参考にしてもらえればと思います。
間違っていたり、おかしな点がありましたら、コメントいただけると幸いです。🙇♂️
対象読者
ESModulesとCommonJSをある程度理解している人向けに書いています。
前提
この記事ではPackage ManagerはYarnを使用します。
npm
, pnpm
を使用する場合は適宜読み替えてください。
以下検証で使用したツールとversionです。
- Node.js(v18.16.0)
- Yarn(v1.22.18)
事前準備
Node.jsでESModulesを使用する
Node.jsでESModulesを使用する場合、module systemをESModulesにする[1]必要があります。
package.jsonを以下のように設定します。
{
...
"type": "module"
}
Jestをinstallする
yarn add --dev jest
JavaScript
まずはJavaScriptを使用したテストです。
Jestの設定
mjs
ファイルはJestのデフォルト設定[2]ではテストファイルから対象外になっています。そのため設定を以下のように変更します。
export default {
testMatch: [
"**/__tests__/**/*.?(m)[jt]s?(x)",
"**/?(*.)+(spec|test).?(m)[tj]s?(x)",
],
}
npm scripts追加
{
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
# yarnの場合はこちらも可能
"test": "yarn node --experimental-vm-modules $(yarn bin jest)"
}
}
テスト対象を作成
export function sum(a, b) {
return a + b;
}
テストファイルを作成
import { sum } from "./sum.mjs";
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
Test
以下のコマンドを実行し、テストします。
yarn test
結果
PASS ./sum.test.mjs
✓ adds 1 + 2 to equal 3 (1 ms)
TypeScript
次にTypeScriptを使用したコードをテストするケースです。
必要なパッケージをinstall
Jest以外に以下のパッケージをinstallします
yarn add -D @types/jest ts-jest typescript
Jestの設定
ESM Support | ts-jestを参考に設定します。
custom resolverを作成
mjs
拡張子を解決するresolverを作成します。
ts-jestのドキュメントにシンプルな例[3]がリンクされていますので、こちらを参考にmjs-resolver.cjs
を作成します。
const mjsResolver = (path, options) => {
const mjsExtRegex = /\.mjs$/i;
const resolver = options.defaultResolver;
if (mjsExtRegex.test(path)) {
try {
return resolver(path.replace(mjsExtRegex, '.mts'), options)
} catch {
// use default resolver
}
}
return resolver(path, options);
}
module.exports = mjsResolver;
jest.config.mjsを作成
次にjest.config.mjs
を作成します。
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
preset: 'ts-jest/presets/default-esm',
moduleFileExtensions: ['js', 'mjs', 'cjs', 'jsx', 'ts', 'mts', 'tsx', 'json', 'node'],
resolver: '<rootDir>/mjs-resolver.cjs',
testMatch: [
'**/__tests__/**/*.?(m)[jt]s?(x)',
'**/?(*.)+(spec|test).?(m)[tj]s?(x)',
],
transform: {
'^.+\\.m?tsx?$': [
'ts-jest',
{
useESM: true,
},
],
},
}
tsconfig作成
yarn run tsc --init
以下のようにtsconfig.jsonを書き換えます。
{
"compilerOptions": {
// ...
"module": "Node16", // or "NodeNext"
"target": "ESNext",
"moduleResolution": "Node16", // or "NodeNext"
"esModuleInterop": true
}
}
npm scripts追加
{
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
# yarnの場合はこちらも可能
"test": "yarn node --experimental-vm-modules $(yarn bin jest)"
}
}
テスト対象を作成
export function sum(a: number, b: number): number {
return a + b;
}
テストファイルを作成
import { sum } from "./sum.mjs";
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
Test
以下のコマンドを実行し、テストします。
yarn test
結果
PASS ./sum.test.mts
✓ adds 1 + 2 to equal 3 (1 ms)
以上です。
Discussion