我用Apollo设置了一个React应用程序,它有一个 Package 器组件来处理从网络加载数据,这样下面的每个组件都可以直接从Apollo缓存中查询数据,而不必担心处理加载状态。因此,我的组件看起来像这样:
export const COUNT_OFF_ADAPTER_QUERY = gql`
query CountOffAdapterQuery($vampId: ID!) {
vamp(id: $vampId) @client {
id
countingOff
countingOffStartTime
}
}
`;
export const CountOffAdapter: React.FC<{}> = () => {
const vampId = useCurrentVampId();
const {
data: {
vamp: { countingOff, countingOffStartTime }
}
} = useQuery<CountOffAdapterQuery>(COUNT_OFF_ADAPTER_QUERY, {
variables: { vampId }
});
const prev = usePrevious({ countingOff, countingOffStartTime });
const countOff = useCountOff();
useEffect(() => {
// Do react stuff
}, [countOff, countingOff, prev]);
return null;
};
在实践中(在浏览器中),这非常有效,因为在应用程序中Apollo将立即从该高速缓存返回数据,因此useQuery
调用的loading
结果永远不会是true
,我可以解构数据,在后续的钩子中使用它,等等。
然而,当测试时,似乎MockedProvider
* 必然 * 将loading
返回为true
,测试编写者无法控制是否跳过该状态注意,当useQuery
返回loading
为true
时,渲染我的组件将出错,因为它正在解构data
,这是未定义的。正因为如此,我永远不能在测试失败的情况下通过加载状态。
下面是我的测试代码:
it("works", async () => {
(useCurrentVampId as jest.Mock).mockImplementation(
() => "6070dedd58d7bf715eb2a6c5"
);
const component = mount(
<MockedProvider
mocks={[
{
request: {
query: COUNT_OFF_ADAPTER_QUERY,
variables: {
vampId: "6070dedd58d7bf715eb2a6c5"
}
},
result: {
data: {
vamp: {
id: "6070dedd58d7bf715eb2a6c5",
countingOff: true,
countingOffStartTime: 1234
}
}
}
}
]}
addTypename={false}
>
<CountOffAdapter></CountOffAdapter>
</MockedProvider>
);
await wait(0);
component.update();
});
我很好奇是否有办法解决这个问题,如果你能在查询mock中指定loading: false
就好了,但是你不能。
1条答案
按热度按时间qvsjd97n1#
我正在使用Next.js,我主要做服务器端渲染,所以我遇到了和你一样的情况,我决定进一步研究一下。看起来apollo-client在实际的mock中提供了延迟 prop ,例如:
但这也无济于事,所以我更深入地研究了源代码,在看到以下内容后,一切都变得清晰起来:
正如你在这里看到的,delay只作为setTimeout的毫秒参数使用,这是一个async code -〉means将添加在javascriptqueue(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop)中的sync code之后。所以,为delay字段提供什么值并不重要。
你的问题的最后结论:目前无法跳过加载状态。