使用Apollo的MockedProvider在故事书中可以进行动态模拟吗?

时间:2019-06-05 00:48:58

标签: graphql apollo storybook

在我的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,我将不再获得模拟响应,变量{...}”。

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

1 个答案:

答案 0 :(得分: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 进行一些操作;但这是它的要点。

祝你好运!