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

Posted

技术标签:

【中文标题】React Apollo MockProvider 总是加载,从不提供数据【英文标题】:React Apollo MockProvider always loading, never giving data 【发布时间】:2018-02-15 06:01:44 【问题描述】:

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

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

我尝试过的事情:

    在线查找(找到this similar question,但由于没有答案,我想我会制作一个新的,提供更多信息) 在测试 (export function Component) 时尝试在没有 graphql 的情况下导出组件,但在测试嵌套组件时不起作用 尝试尽可能简化(其结果在示例中)

【问题讨论】:

你在用什么?酶? @arcom 是的。添加标签 【参考方案1】:

是的,我也遇到了这个问题。有趣的是,如果我将控制台日志添加到组件本身,我可以看到数据最终可以正常到达那里。但由于某种原因,wrapper 仍将只包含我们的“正在加载...” 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();
)

【讨论】:

是的,这很奇怪,但确实有效。对于其他阅读本文的人,请用 wait 替换 setTimeout 中的 expect 以 0 时间 太棒了,我已经坚持了好几天了......非常感谢【参考方案2】:

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

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) 无论如何也不会始终如一地处理这种情况。

【讨论】:

【参考方案3】:

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

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

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

import  CURRENT_USER_QUERY  from './User';

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

【讨论】:

以上是关于React Apollo MockProvider 总是加载,从不提供数据的主要内容,如果未能解决你的问题,请参考以下文章

Apollo Mock Error state -> Error: No more mocked response for the query

React Apollo 显示“react-apollo 仅支持每个 HOC 的查询、订阅或突变”错误

Prisma Playground 中的 React + Apollo“入门”错误

Apollo:在订阅更新时更新 React 道具?

找不到模块:无法解析“apollo-link-context”-REACT,APOLLO-SERVER

使用 `react-apollo-hooks` 和 `useSubscription` 钩子