用Jest嘲笑的服务会导致“不允许jest.mock()的模块工厂引用任何范围外的变量".错误 [英] Service mocked with Jest causes "The module factory of jest.mock() is not allowed to reference any out-of-scope variables" error
问题描述
我正在尝试模拟对服务的调用,但是我在以下消息中苦苦挣扎: jest.mock()
的模块工厂不允许引用任何范围外的变量
I'm trying to mock a call to a service but I'm struggeling with the following message: The module factory of jest.mock()
is not allowed to reference any out-of-scope variables.
我正在使用具有ES6语法,玩笑和酵素的babel.
I'm using babel with ES6 syntax, jest and enzyme.
我有一个名为Vocabulary
的简单组件,该组件从vocabularyService
获取VocabularyEntry
-对象的列表并进行渲染.
I have a simple component called Vocabulary
which gets a list of VocabularyEntry
-Objects from a vocabularyService
and renders it.
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
:
Now I want to mock the vocabularyService
in a test:
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.
Running the test causes an error: Vocabulary.spec.js: babel-plugin-jest-hoist: The module factory of jest.mock()
is not allowed to reference any out-of-scope variables.
Invalid variable access: VocabularyEntry.
据我所知,我无法使用VocabularyEntry,因为它没有声明(因为开玩笑将模拟定义移到了文件的顶部).
As far as I unterstood, I cannot use the VocabularyEntry because it is not declares (as jest moves the mock definition to the top of the file).
谁能解释我该如何解决?我看到了需要在模拟调用中引用这些引用的解决方案,但我不明白如何使用类文件来实现.
Can anyone please explain how I can fix this? I saw solutions which required the references insinde the mock-call but I do not understand how I can do this with a class file.
推荐答案
问题是所有jest.mock
都将在编译时提升到实际代码块的顶部,在这种情况下,这是文件的顶部.此时,尚未导入VocabularyEntry
.您可以将mock
放在测试的beforeAll
块中,或使用jest.mock
这样:
The problem is that all jest.mock
will be hoisted to the top of actual code block at compile time, which is the in this case the top of the file. At this point VocabularyEntry
is not imported. You could either put the mock
in a beforeAll
block in your test or use jest.mock
like this:
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")]
}))
这将首先使用一个简单的间谍对模块进行模拟,并在导入所有内容后设置模拟的真实实现.
This will first mock the module with a simple spy and after all stuff is imported it sets the real implementation of the mock.
这篇关于用Jest嘲笑的服务会导致“不允许jest.mock()的模块工厂引用任何范围外的变量".错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!