TypeScriptのコードをJestでテストする
やり方には、ts-jestを使う方法と、babelを使う方法がある。
babelを使うやり方は、https://kinosuke.hatenablog.jp/entry/2020/01/29/115640 と同じアプローチ。preset-envをpreset-typescriptにするだけ。ただし、型チェックはできない。
今回は、型チェックもやってほしいので、ts-jestを使う方法を試してみる。
ライブラリのインストール
npm install --save-dev jest ts-jest @types/jest
- @types/jest
- jestの型を定義
- ts-jest
- Jest用のTypeScriptプリプロセッサ
- JestがTypeScriptをトランスパイルできるようになる
Jestを設定する
# 設定ファイルを作成する npx jest --init
${APP_DIR}/jest.config.js
に以下を書き込む。
module.exports = { // Jestの検索対象となるパス roots: [ "<rootDir>" ], // テストコードを書いたファイルを特定するための条件 "testMatch": [ "**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)" ], // ts/tsxファイルに対してts-jestを使うよう設定 "transform": { "^.+\\.(ts|tsx)$": "ts-jest" }, }
テストスクリプトを準備する
${APP_DIR}/package.json
に以下を追加
{ "scripts": { # 略 "test": "jest", "test:w": "jest --watch", "test:coverage": "jest --coverage" }, # 略 }
テストコードを書いてみる
src/Animal.ts
にテスト対象コードを書く。
export class Animal { animaltype: string; name: string; constructor(animalType: string, name: string) { this.animaltype = animalType; this.name = name; } say(): string { let content: string = "`Hello. I am ${this.name} of ${this.animaltype}.`"; return content; } }
test/Animal.test.ts
にテストコードを書く。
import { Animal } from '../src/Animal'; describe('say', () => { it("`Hello`を含む文字列を返すこと", () => { let animal = new Animal('cat', 'popuko'); let reg = /Hello/; let result = animal.say(); expect(reg.test(result)).toEqual(true); }) })
テストを実行する
# 全部をテストする npm run test test/. # ファイル名を指定してテストする npm run test test/Animal.test.ts
補足
テスト時に以下の警告が出た。
importで問題がある場合は、esModuleInterop
を使うとよさそうですね、とのこと。
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
毎回警告が出るのは気になるので、tsconfig.json
に以下を追加。
{ "compilerOptions": { # 略 "esModuleInterop": true } }
esModuleInterop
って何がいいの?
// esModuleInterop無効の場合 // CommonJSのモジュールは、requireで読み込まないとだめ。 `const moment = require('moment');` // esModuleInterop有効な場合 // CommonJSのモジュールもES Modulesと同じ書き方で読み込めるようになる! import moment from 'moment'