サービスの呼び出しをモックしようとしていますが、次のメッセージで苦労しています:jest.mock()
のモジュールファクトリは、スコープ外の変数を参照することはできません =。
ES6シンタックス、jest、酵素でbabelを使用しています。
Vocabulary
からVocabularyEntry
- Objectsのリストを取得してレンダリングする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: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")]
}))
これは最初に単純なスパイでモジュールをモックし、すべてのものがインポートされた後、モックの実際の実装を設定します。
新しいJest [私の場合は19から21]にアップグレードするときに同様のエラーが発生する場合は、jest.mock
からjest.doMock
。
ここにあります– https://github.com/facebook/jest/commit/6a8c7fb874790ded06f4790fdb33d8416a7284c8
これは私があなたのコードのためにそれを解決する方法です。
モックされたコンポーネントを、「mock」というプレフィックスが付いた変数に保存する必要があります。この解決策は、私が得ていたエラーメッセージの最後にある注に基づいています。
注:これは、初期化されていないモック変数から保護するための予防措置です。モックが遅延して必要であることが保証されている場合、
mock
で始まる変数名が許可されます。
import {shallow} from 'enzyme';
import React from 'react';
import Vocabulary from "../../../src/components/Vocabulary ";
import {VocabularyEntry} from '../../../src/model/VocabularyEntry'
const mockVocabulary = () => new VocabularyEntry("a", "a1");
jest.mock('../../../src/services/vocabularyService', () => ({
default: mockVocabulary
}));
describe("Vocabulary tests", () => {
test("renders the vocabulary", () => {
let $component = shallow(<Vocabulary/>);
// expect something
});