【问题标题】:Are dynamic mocks possible in storybooks using Apollo's MockedProvider?使用 Apollo 的 MockedProvider 在故事书中是否可以进行动态模拟?
【发布时间】:2019-10-20 12:29:30
【问题描述】:

在我的 React 故事书中,我希望能够玩弄使用 graphQL 查询和突变(用 Apollo 实现)的组件。

使用 MockedProvider 可以正常工作,只要我提前指定确切的突变,包括它们的输入。

我想知道是否有可能/如何不提前指定输入,以接受任何输入。


export const MyComponent = () => (
    <Mutation mutation={gql`some mutation`}>
      {(doMutation, { loading, error, data }) => (
        <Button onClick={()=> doMutation({input: {
          someInput: Math.rand()*10 // Would be fine if this was 1.
        }}) />
        {data ? <>Result: {data.someResult}</> : null}
      )
    </Mutation>
)


storiesOf('MyComponent', module)
  .add('some story', () => (
    <StaticRouter context={{}}>
      <MockedProvider
        mocks={[
          {
            request: {
              query: gql`some query...`,
              variables: { input: { someInput: '1' } },
            },
            result: { data: { someResult: '1' } },
          },
        ]}
        addTypename={true}
      >
        <MyComponent />
      </MockedProvider>
    </StaticRouter>
  ))

在上面的伪示例中,如果我发送 '1' 作为输入,故事书将正常工作,但不适用于任何其他数字 - 模拟必须完全匹配,否则我会得到“对于 someMutation 没有更多模拟响应变量 {...}"。

这在测试中不是问题,但在故事书中,能够使用任何值进行测试会很好。

【问题讨论】:

  • 您好,很抱歉再次提出一个老问题,但您是否找到任何解决方案或解决方法?我有同样的问题,GQL 查询变量使用当前日期时间,无法在 Storybook 中模拟它......
  • 嗨@dessskris 我找到了实现目标的方法,也许它也适合你。我所做的不是直接使用模拟提供程序,而是依赖注入突变/查询钩子。这样我就可以覆盖我想要的功能。我们使用了一个名为 MagneticDI 的好工具来帮助它变得非常简单。

标签: graphql apollo storybook


【解决方案1】:

我找到了一种方法来做我想做的事,尽管没有使用MockedProvider

首先,转换为钩子。

export const MyComponent = () => {
  const [doMutation, {loading, data, error}] = useMutation(gql`some mutation`)

  return (
    <Button onClick={()=> doMutation({input: {
      someInput: Math.rand()*10 // Would be fine if this was 1.
    }}) />
    {data ? <>Result: {data.someResult}</> : null}
 );
}

现在依赖注入突变钩子,使用react-magnetic-di

export const useMyMutation = () => useMutation(gql`some mutation`)

export const MyComponent = () => {
  di(useMyMutation)
  const [doMutation, {loading, data, error}] = useMyMutation() // Will be the in-scope variable `useMyMutation` from above unless expressly injected during stories/tests.

  return (
    <Button onClick={()=> doMutation({input: {
      someInput: Math.rand()*10 // Would be fine if this was 1.
    }}) />
    {data ? <>Result: {data.someResult}</> : null}
 );
}

现在您可以使用自定义实现编写故事/测试。

export const useMockMyMutation = injectable(
  myMutation, // imported from the component, types are checked against it.
  () => [function thisWillBeDoMutation(){}, {loading: false, data: {}, error: null}])

storiesOf('MyComponent', module)
  .add('some story', () => (
    <StaticRouter context={{}}>
      <DiProvider target={MyComponent} use={[useMockMyMutation]}>
        <MyComponent />
      </DiProvider>
    </StaticRouter>
  ))

所以我们直接为 doMutation 提供任何函数,如果需要,您可以更改用于 loading/data/error 等的值。

我们制作了很多工具以使其更加精简,因此提取此示例有点棘手,因此您需要尝试使用 react-magnetic-di;但这是它的要点。

祝你好运!

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 2020-09-14
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2013-10-08
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多