【发布时间】:2019-07-27 01:48:04
【问题描述】:
我在为我的 React 组件所依赖的服务类工作而苦苦挣扎——在组件内部初始化的类。我正在使用 Jest“手动模拟”方法。我正在打电话给jest.mock,但每次我运行测试时,他们都使用真正的服务类而不是模拟。
我已经看到它表明我正在尝试做的事情(在下面的示例中,模拟 UserService)对于 Jest 是不可能的。我知道在这个例子中,getUsers 调用可能只是一个导出函数,但在我的实际项目中,我会有需要模拟的完整类;这只是一个过于简单的例子。
我的问题归结为:我可以在使用 Jest 测试 React 组件时模拟出这样的类吗?如果可以,我缺少什么?这是一个不工作的模拟示例。
编辑:GitHub 中的代码:https://github.com/cvs-mrussell/ReactJestMockTest
编辑 2:如果我将组件转换为类,则模拟工作。测试 React 钩子有问题吗?阅读此内容,在 React 18.9.0-alpha 之前,在 useEffect 中使用异步调用进行测试似乎很棘手,此时专门引入了 act 的异步版本来解决该场景(参考:@987654322 @)。因此,由于异步问题,看起来我无论如何都需要重新测试我的测试,但没有回答为什么我的模拟没有在这个特定场景中使用(使用钩子)。
// /src/Services/UserService.ts
export default class UserService {
public async getUsers(): Promise<IUser[]> {
console.debug('Real getUsers');
const response = await axios.get(https://jsonplaceholder.typicode.com/users);
return response.data;
}
}
// /src/Services/__mocks__/UserService.ts
export default class UserService {
public async getUsers(): Promise<IUser[]> {
console.debug('Mock getUsers');
return Promise.resolve([
{ id: 1, name: 'User 1', email: 'email1' },
{ id: 2, name: 'User 2', email: 'email2' },
]);
}
}
import React, { useEffect, useState } from 'react';
import UserService from '../../Services/UserService';
import IHomeState from './IHomeState';
import IUser from '../../Interfaces/IUser';
const Home = (): JSX.Element => {
const [state, setState] = useState({
users: [],
} as IHomeState);
async function loadData(): Promise<void> {
const service = new UserService();
const users = await service.getUsers();
setState({ users });
}
useEffect((): void => { loadData(); }, []);
const userList = state.users.map((el: IUser): JSX.Element => (
<li key={el.id}>
{el.name}
</li>
));
return (
<ul>
{userList}
</ul>
);
}
export default Home;
// Test
import React from 'react';
import { shallow } from 'enzyme';
import UserService from '../../Services/UserService';
import Home from './Home';
jest.mock('../../Services/UserService');
it('renders without crashing', (): void => {
const wrapper = shallow(<Home />);
expect(wrapper.exists()).toBe(true);
});
【问题讨论】: