小编典典

使用Jest嘲笑的服务导致“不允许jest.mock()的模块工厂引用任何范围外的变量”错误

reactjs

我正在尝试模拟对服务的调用,但是我在以下消息中苦苦挣扎: 的模块工厂jest.mock()不允许引用任何范围外的变量

我正在使用带有ES6语法,笑话和酶的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
 }
 }

vocabularyServiseIST很简单:

  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,因为它没有声明(因为开玩笑将模拟定义移到了文件的顶部)。

谁能解释我该如何解决?我看到了需要在模拟调用中引用这些引用的解决方案,但是我不明白如何使用类文件来实现。


阅读 366

收藏
2020-07-22

共1个答案

小编典典

问题在于,所有这些都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")]
}))

这将首先使用一个简单的间谍对模块进行模拟,并在所有内容导入后设置模拟的实际实现。

2020-07-22