尽管我认为您已经在这样做,但首先要注意的是,您实际上不应该从测试中获取任何数据——您应该模拟结果。
完成此操作后,您将使用该waitFor
实用程序来帮助您进行异步测试——该实用程序基本上接受一个返回期望 ( expect
) 的函数,并将在测试的那个点保持直到满足期望。
让我们举个例子。以我在下面创建的虚构组件为例:
const MyComponent = () => {
const [data, setData] = useState();
useEffect(() => {
MyService.fetchData().then((response) => setData(response));
}, []);
if (!data) {
return (<p>Loading...</p>);
}
// else
return (
<div>
<h1>DATA!</h1>
<div>
{data.map((datum) => (<p>{datum}</p>))}
</div>
</div>
);
}
所以对于你的测试,你会做
import MyService from './MyService';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
const mockData = ['Spengler', 'Stanz', 'Venkman', 'Zeddmore'];
beforeEach(() => {
jest.spyOn(MyService, 'fetchData')
.mockImplementation(
() => new Promise((res) => setTimeout(() => res(mockData), 200))
);
});
afterEach(() => {
MyService.fetchData.mockRestore();
});
it('displays the loading first and the data once fetched', async () => {
render(<MyComponent />);
// before fetch completes
expect(screen.getByText(/Loading/)).toBeInTheDocument();
expect(screen.queryByText('DATA!')).toBeNull();
// after fetch completes..
// await waitFor will wait here for this to be true; if it doesn't happen after about five seconds the test fails
await waitFor(() => expect(screen.getByText('DATA!')).toBeInTheDocument());
expect(screen.queryByText(/Loading/)).toBeNull(); // we don't have to await this one because we awaited the proper condition in the previous line
});
});
这未经测试,但类似这样的东西应该可以工作。您的模拟方法可能会因您构建获取的方式而有所不同。