コピペコードで快適生活

明日使えるソースを自分のために

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'

参考