问题描述
我正在尝试在测试中模拟获取状态。成功模拟了带有数据的状态和带有错误的状态。您可以在下面找到一个示例:
const createMenuWithGraphQL = (graphqlData: MockGraphQLResponse): [JSX.Element,MockGraphQLClient] => {
const mockGraphQLClient = {
executeQuery: jest.fn(() => fromValue(graphqlData)),executeMutation: jest.fn(() => never),executeSubscription: jest.fn(() => never),};
return [
<GraphQLProvider key="provider" value={mockGraphQLClient}>
<Menu {...menuConfig} />
</GraphQLProvider>,mockGraphQLClient,];
};
it('displays submenu with section in loading state after clicking on an item with children',async () => {
const [Component,client] = createMenuWithGraphQL({
fetching: true,error: false,});
const { container } = render(Component);
const itemConfig = menuConfig.links[0];
fireEvent.click(screen.getByText(label));
await waitFor(() => {
const alertItem = screen.getByRole('alert');
expect(client.executeQuery).toBeCalledTimes(1);
expect(container).toContainElement(alertItem);
expect(alertItem).toHaveAttribute('aria-busy','false');
});
});
该组件如下所示:
export const Component: FC<Props> = ({ label,identifier }) => {
const [result] = useQuery({ query });
return (
<div role="group">
{result.fetching && (
<p role="alert" aria-busy={true}>
Loading
</p>
)}
{result.error && (
<p role="alert" aria-busy={false}>
Error
</p>
)}
{!result.fetching && !result.error && <p>Has data</p>}
</div>
);
};
我不知道我在做什么错。当我运行测试时,它说fetching
是false
。任何帮助将不胜感激。
解决方法
维护者在这里
我认为这里的问题是您正在executeQuery
中同步返回。让我们看看会发生什么。
- 您的组件将挂载并检查缓存中是否存在同步状态。
- 之所以如此,是因为我们只做
executeQuery: jest.fn(() => fromValue(graphqlData)),
我们可以看到,这实际上可以归结为相同的结果,就好像结果只是从缓存中出来一样(我们不需要点击API,因此也不需要点击获取)。
我们可以通过添加setTimeout,...
来解决此问题,但是Wonka
(urql使用的流媒体库)为此提供了内置解决方案。
我们可以利用delay
运算符来模拟获取状态:
const mockGraphQLClient = {
executeQuery: jest.fn(() => pipe(fromValue(data),delay(100)),};
现在,我们可以在前100毫秒内正确检查fetching
状态,此后,我们便可以利用waitFor
检查后续状态。