1. ホーム
  2. javascript

[解決済み] Jestを使用してES6モジュールのインポートをモックするにはどうすればよいですか?

2022-03-26 04:06:02

質問

の1つをテストしたいのですが ES6 モジュールは、特定の方法で別の ES6 モジュールを呼び出します。とは ジャスミン これは非常に簡単です。

アプリケーションのコードです。

// myModule.js
import dependency from './dependency';

export default (x) => {
  dependency.doSomething(x * 2);
}

そして、テストコードです。

//myModule-test.js
import myModule from '../myModule';
import dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    spyOn(dependency, 'doSomething');

    myModule(2);

    expect(dependency.doSomething).toHaveBeenCalledWith(4);
  });
});

Jestで相当するものは何ですか?こんな単純なことをやりたいような気もするのですが、それを理解するために髪をかきむしっています。

一番近かったのは importrequire のようなもので、テストや関数の中に移動させます。どちらも私がやりたいことではありません。

// myModule.js
export default (x) => {
  const dependency = require('./dependency'); // Yuck
  dependency.doSomething(x * 2);
}

//myModule-test.js
describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    jest.mock('../dependency');

    myModule(2);

    const dependency = require('../dependency'); // Also yuck
    expect(dependency.doSomething).toBeCalledWith(4);
  });
});

ボーナスポイントとしては、全体の動作が dependency.js はデフォルトのエクスポートです。しかし、Jasmineではデフォルトエクスポートのスパイはうまくいかない(少なくとも私はうまくいかなかった)ことを知っているので、Jestでもそれが可能であるという希望を抱いていません。

どうすれば解決するの?

2020年まで早送りすると、このブログ記事が解決策になることがわかりました。 Jestモックのデフォルトと名前付きエクスポート

ES6モジュール構文のみを使用。

// esModule.js
export default 'defaultExport';
export const namedExport = () => {};

// esModule.test.js
jest.mock('./esModule', () => ({
  __esModule: true, // this property makes it work
  default: 'mockedDefaultExport',
  namedExport: jest.fn(),
}));

import defaultExport, { namedExport } from './esModule';
defaultExport; // 'mockedDefaultExport'
namedExport; // mock function

また、一つ知っておかなければならないのは、(私が理解するのに時間がかかったのですが) jest.mock() はテストの中では呼べないということです;モジュールのトップレベルで呼ぶ必要があります。しかし、テストごとに異なるモックを設定したい場合は、個々のテストの内部でmockImplementation()を呼び出すことができます。