Ria*_*Ria 22 unit-testing reactjs jestjs babeljs
我正在尝试模拟对服务的调用,但我正在使用以下消息:模块工厂jest.mock()不允许引用任何超出范围的变量.
我正在使用带有ES6语法,开玩笑和酶的babel.
我有一个简单的组件Vocabulary,它VocabularyEntry从a 获取-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
}
}
Run Code Online (Sandbox Code Playgroud)
这vocabularyServise很简单:
import {VocabularyEntry} from '../model/VocabularyEntry';
class VocabularyService {
constructor() {
this.vocabulary = [new VocabularyEntry("a", "b")];
}
}
export default new VocabularyService();`
Run Code Online (Sandbox Code Playgroud)
现在我想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
});
Run Code Online (Sandbox Code Playgroud)
});
运行测试会导致错误:Vocabulary.spec.js:babel-plugin-jest-hoist:jest.mock()不允许模块工厂引用任何超出范围的变量.无效的变量访问:VocabularyEntry.
据我所知,我不能使用VocabularyEntry,因为它没有声明(因为jest将模拟定义移动到文件的顶部).
任何人都可以解释我如何解决这个问题?我看到了需要引用的解决方案才能使用模拟调用,但我不明白如何使用类文件执行此操作.
Mis*_*lin 19
如果在升级到较新的Jest [在我的情况下为19到21]时出现类似的错误,您可以尝试更改jest.mock为jest.doMock.
在这里找到了这个 - https://github.com/facebook/jest/commit/6a8c7fb874790ded06f4790fdb33d8416a7284c8
And*_*rle 12
问题是所有都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")]
}))
Run Code Online (Sandbox Code Playgroud)
这将首先使用一个简单的间谍模拟模块,然后在导入所有内容后,它会设置模拟的真实实现.
jest.mock("../../../src/services/vocabularyService", () => {
// eslint-disable-next-line global-require
const VocabularyEntry = require("../../../src/model/VocabularyEntry");
return {
vocabulary: [new VocabularyEntry("a", "a1")]
};
});
Run Code Online (Sandbox Code Playgroud)
我认为它也应该与动态导入一起使用,而不是require但没有设法使其工作。
这就是我为您的代码解决的方式。
您需要将模拟的组件存储在名称以“ 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
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11139 次 |
| 最近记录: |