1. ホーム
  2. javascript

[解決済み] Jest モッキング デフォルトのエクスポート - require vs import

2022-03-14 19:53:59

質問

このあたりでjestによるデフォルトエクスポートのモッキングに言及した質問を見かけますが、すでに質問されていないような気がします。

テスト対象のモジュールの依存関係のデフォルトエクスポートをモックする際、モジュールがES6 importステートメントで依存関係をインポートしている場合、テストスイートの実行に失敗し、次のように表示されます。 TypeError: (0 , _dependency.default) is not a function しかし、そのモジュールが require().default の代わりに呼び出す。

私の理解では import module from location を直訳すると const module = require(location).default なぜこのようなことが起こるのか、非常に混乱しています。私はむしろ、コードスタイルを一貫させて require の呼び出しは、元のモジュールに含まれています。

何か方法があるのでしょうか?

モックを使ったテストファイル。

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

jest.mock('./dependency', () => {
   return {
      default: jest.fn()
   };
});

// This is what I would eventually like to call
it('calls the mocked function', () => {
   expect(dependency).toHaveBeenCalled();
});

依存関係.js

export default () => console.log('do something');

module.js (動作しません)

import dependency from './dependency.js';
dependency();

module.js (動作中)

const dependency = require('./dependency.js').default;
dependency();

解決方法は?

のどちらかを使用することができます。 es6 import または require js を使用して、jestのテストにjsファイルをインポートします。

を使用する場合 es6 import の場合、jestはすべての依存関係を解決しようとし、またインポートしているクラスのコンストラクタを呼び出すことを知っておく必要があります。このステップの間、あなたは モック となります。依存関係が正常に解決されてから、モックの作成に取り掛かることができます。

また、ご覧のように ここで jestはデフォルトでjest.mockをファイルの先頭に持ってくるので、importを配置する順序はあまり重要ではありません。

しかし、あなたの問題はそれとは異なります。モック関数は、あなたがjsファイルを require js .

jest.mock('./dependecy', () => {
   return {
      default: jest.fn()
   };
});

を使用してファイルをインポートする場合 require js このような構造になっています。

というクラスをインポートしたと仮定します。 require js というメソッドがあり、それをテスト内で呼び出すには、次のようにします。

const test = require('../Test');
test.default.doSomething();

を使ってインポートする場合 es6 import しかし、その方法は異なります。同じ例を使って

import Test from '../Test';
Test.doSomething();

編集:もし、あなたが es6 import に変更し、モック関数を作成します。

jest.mock('./dependecy', () => jest.fn());