我正在努力使模拟能够为我的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
的异步版本来解决该情况( ref:https://github.com/facebook/react/issues/14050#issuecomment-480272261)。因此,由于异步问题,我似乎仍然需要重新测试,但无法回答为什么在这种特殊情况下(使用挂钩)未使用我的模拟游戏。
// /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);
});
答案 0 :(得分:0)
我首先会尝试内联模拟函数,以检查您是否在正确执行其他所有操作,例如:
// Test
import React from 'react';
import { shallow } from 'enzyme';
import UserService from '../../Services/UserService';
import Home from './Home';
const mockedGetUserFunction = async (): Promise<IUser[]> => { /* implement mock */ };
jest.mock('../../Services/UserService');
mockedGetUserFunction.bind(UserService);
it('renders without crashing', (): void => {
const wrapper = shallow(<Home />);
expect(wrapper.exists()).toBe(true);
});
此外,请尝试避免将服务默认导出(这将需要您随后调整导入):
export default class UserService => export class UserService