React Apollo MockProvider 总是加载,从不提供数据

React Apollo MockProvider always loading, never giving data

我正在尝试测试一个使用 graphql 的组件,但是当使用 Apollo 的 MockProvider 时,我从来没有得到数据,它只是每次都说 loading = true。

一个完整的、极简主义的例子是here

我尝试过的事情:

  1. 在线查找(找到 this similar question,但由于没有答案,我想我会制作一个包含更多信息的新答案)
  2. 尝试在测试时不使用 graphql 导出组件 (export function Component),但在测试嵌套组件时这不起作用
  3. 尽量简化(结果在例子中)

是的,我也 运行 关注这个问题。有趣的是,如果我将控制台日志添加到组件本身,我可以看到数据最终顺利到达那里。但出于某种原因,wrapper 仍然只包含我们的 "Loading ..." UI.

原来你需要调用 wrapper.update() 来让包装器重新呈现它的内容。

这对我有用,但似乎不太理想,所以如果其他人有解决方法,请告诉我!现在我们的测试看起来像:

it('should render the HeroDiv if there is guide data', async () => {
  const wrapper = mount(
    <MockedProvider mocks={mocksWithGuideData} addTypename={false}>
      <Hero {...props} />
    </MockedProvider>
  );

  await wait(0);
  wrapper.update();

  expect(wrapper.find('HeroDiv').exists()).toBeTruthy();
})

我不喜欢 await wait(0) 方法。查看 apollo 文档:

For more complex UI with heavy calculations, or delays added into its render logic, the wait(0) will not be long enough.

这意味着您的测试可能不稳定。为了解决这个问题,我使用 wait-for-expect 包(也包含在文档中:https://www.apollographql.com/docs/guides/testing-react-components.html#Testing-mutation-components):

it('should render the HeroDiv if there is guide data', async () => {
  const wrapper = mount(
    <MockedProvider mocks={mocksWithGuideData} addTypename={false}>
      <Hero {...props} />
    </MockedProvider>
  );

  await waitForExpect(() => {
    wrapper.update();
    expect(wrapper.find('HeroDiv').exists()).toBeTruthy();
  });
})

waitForExpect 基本上会进行轮询,直到条件完成并在 5 秒后超时。这保证了您的测试将完成,只要您的查询在 5 秒之前完成,如果您使用的是 MockedProvider,那绝对应该如此。

文档指出了一个警告:The risk of using a package like this everywhere by default is that every test could take up to five seconds to execute (or longer if the default timeout has been increased).但根据我的经验,使用 MockedProvider 永远不会发生这种情况。另外,await wait(0) 无论如何也不会始终如一地处理这种情况。

此外,请确保您在组件文件中导入的查询与您在测试文件中使用的查询完全相同。例如,我有一个问题,我的 mocks 道具不会将任何数据传递给 MockedProvider,因为我正在导入:

import { CURRENT_USER_QUERY } from '../lib/queries';

在 PleaseSigin.js 中,我正在导入:

import { CURRENT_USER_QUERY } from './User';

在 PleaseSignin.test.js 中。显然,即使两个查询相同,但就 Jest 而言,它们并不相同。