コンテンツにスキップ

[Jest] FAQ

テストの実行について

1テストSuiteずつ直列に実行したい

--runInBandオプションをつける

テストの実行が遅い

--maxWorkers=1オプションをつける。
デフォルトは3であるため、特にTypeScriptなどtranspileが必要な場合は遅くなることが多い。

テストの書き方について

テスト対象の中でimportしているモジュールのMockを作りたい

companyService.fetchclients/apiを使っているケース。
clients/apiをMock化して、副作用の無い状態でcompanyService.fetchをテストしたい。

jest.mockでモック化すれば、それをimportしている箇所全てに影響が出る。

import * as companyService from './company';
import * as api from '../clients/api';
jest.mock('../clients/api');

describe('companyService.fetch', () => {
  beforeAll(() => {
    (svn as any).list.mockReturnValue(['dummy1', 'dummy2']);
  });
  test('テスト', async () => {
    const actual = await companyService.fetch();
    expect(actual).toStrictEqual(['dummy1, dummy2']);
  });
});

モック化したモジュール.プロパティに対して、mockReturnValue(...)で任意の値をreturnさせる。
mockImplementation((arg1, arg2) => arg1 + arg2)のようにすると任意のfunctionを定義できる。

一定時間内で何度か確認してOKかを判定したい

wait-for-exceptを使う.

エラーについて

Decorators are not enabled エラーになる

エラーケース1

以下の場合

If you are using ["@babel/plugin-proposal-decorators", { "legacy": true }], make sure it comes *before* "@babel/plugin-proposal-class-properties" and enable loose mode, like so:
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
    ["@babel/plugin-proposal-class-properties", { "loose": true }]

babel.config.jsplugins配下を以下の順で定義する。
順番が違うと動かない。

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
  ]
}

legacyとlooseの理由を調べる

もちろん該当pluginのインストールは必要。

エラーケース2

以下の場合

Namespaces are not supported.

TypeScriptのnamespaceにデフォルトで対応していないから。

babel.config.jsplugins配下に以下を追加する。

  "plugins": [
    ["@babel/plugin-transform-typescript", {"allowNamespaces": true}],
  ]

デフォルトでは allowNamespaces: false なので明示的指定が必要。
将来はtrueになるらしい。

もちろん該当pluginのインストールは必要。

electronからimportできずエラーになる

Jestはmainを通してelectronを起動していないので当然失敗する。
処理がテストに関係なければ、Mockを作って凌ぐ。

package.json

  # moduleNameMapperに追加
  "jest": {
    "moduleNameMapper": {
      "electron": "<rootDir>/electron-mock.ts"
    }
  }

electron-mock.ts

# `{remote.require("exec").exec`まで呼ばれることを想定
export const remote = {
  require: (required_but_ignored: string) => ({
    exec: undefined
  })
};

間違ってなさそうなのにTypeScriptのテストコードがエラーになる

テストコード以外のフローで、テストコード対象のtsファイルに対するjsファイルが作成されていないかを確認する。
jsファイルが存在するとそちらが優先して使用されてしまう恐れがあるため。