1. ホーム
  2. unit-testing

[解決済み] Jestでモックされたサービスが「jest.mock()のモジュールファクトリは、スコープ外の変数を参照することを許可されていません」エラーを発生させる

2023-05-28 10:52:41

質問

あるサービスの呼び出しをモック化しようとしているのですが、以下のようなメッセージが表示され、困っています。 のモジュールファクトリは jest.mock() のモジュール・ファクトリは、スコープ外の変数を参照することが許可されていません。 .

ES6構文、jest、enzymeでbabelを使っています。

というシンプルなコンポーネントを持っています。 Vocabulary のリストを取得します。 VocabularyEntry -オブジェクトのリストを取得します。 vocabularyService を生成し、それをレンダリングする。

import React from 'react';
import vocabularyService from '../services/vocabularyService';

export default class Vocabulary extends React.Component {

render() {

    let rows = vocabularyService.vocabulary.map((v, i) => <tr key={i}>
            <td>{v.src}</td>
            <td>{v.target}</td>
        </tr>
    );
    // render rows
 }
 }

vocabularyServise は非常にシンプルです。

  import {VocabularyEntry} from '../model/VocabularyEntry';

  class VocabularyService {

  constructor() {
       this.vocabulary = [new VocabularyEntry("a", "b")];
  }
} 
export default new VocabularyService();`

今度は vocabularyService をモック化したいと思います。

import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'

jest.mock('../../../src/services/vocabularyService', () => ({

vocabulary: [new VocabularyEntry("a", "a1")]

}));

describe("Vocabulary tests", () => {

test("renders the vocabulary", () => {

    let $component = shallow(<Vocabulary/>);

    // expect something

});

});

テストを実行すると、エラーが発生します。Vocabulary.spec.js: babel-plugin-jest-hoist.Vocabulary.spec.js: babel-plugin-jest-hoist: のモジュールファクトリは jest.mock() のモジュールファクトリは、スコープ外の変数を参照することが許可されていません。 無効な変数アクセスです。VocabularyEntryです。

私が理解した限りでは、VocabularyEntryは宣言されていないため(jestはモックの定義をファイルの先頭に移動するため)、使用できません。

どなたか、これを修正する方法を説明していただけませんか。私はモック呼び出しの内側に参照を必要とするソリューションを見たが、私はクラスファイルでこれを行うことができる方法を理解していない。

どのように解決するのですか?

問題は、すべての jest.mock はコンパイル時に実際のコードブロックの一番上に持ち上げられるということです。この時点では VocabularyEntry はインポートされません。を置くか、あるいは mock の中に beforeAll ブロックに入れるか、あるいは jest.mock のようにします。

import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
import vocabularyService from '../../../src/services/vocabularyService'

jest.mock('../../../src/services/vocabularyService', () => jest.fn())

vocabularyService.mockImplementation(() => ({
  vocabulary: [new VocabularyEntry("a", "a1")]
}))

これはまず単純なスパイでモジュールをモックし、すべてのものがインポートされた後にモックの本当の実装を設定します。