Search code examples
relayjs

Mock data generation for storybook


I am trying to generate mock data using relay for storybook. My query is

const QUERY_LIST = graphql`
  query modelControllerAllUsersQuery @relay_test_operation {
    allUsers {
      pageInfo {
        hasNextPage
      }
      edges {
        node {
          id
          firstName
          lastName
        }
      }
    }
  }
`

and provided RelayEnvironmentProvider as a decorator to the story. I'm trying to return some default values to my query using custom mock resolvers.

  const customMockResolvers = {
    ...mockResolvers,
    allUsers:() => ({
      pageInfo:{
        hasNextPage:false,
      },
      edges:[
        {
          node:{
            id       :'id',
            firstName:'fname',
            lastName :'lname',
          },
        },
      ],
    }),
  };

and calling it as

(operation) => MockPayloadGenerator.generate(operation, customMockResolvers)

I don't seem to be able to get the default values returned. Currently, it is returning

{"allUsers":{"pageInfo":{"hasNextPage":false},"edges":[{"node":{"id":"<UserNode-mock-id-1>","firstName":"<mock-value-for-field-\"firstName\">","lastName":"<mock-value-for-field-\"lastName\">"}}]}}

What am I doing wrong?


Solution

  • When using the @relay-test-operation, the keys within your customMockResolvers object must match the type name of the fields, which can be different from the field names themselves.

    For example, you could have the following in your schema:

    type Foo {
      id: ID!
      name: String!
    }
    

    and the following query:

    query FooQuery @relay_test_operation {
      foo {
        id
        name
      }
    }
    

    Then the customMockResolvers object would look like this:

    const customMockResolvers = {
      Foo: () => ({
        id: "fooId",
        name: "fooName"
      })
    }
    

    Notice that I'm passing in Foo as the key instead of foo.

    You can check your schema and see what the the type name of allUsers is. I suspect it would be something like AllUsers or allUsersConnection, or something similar.


    Also, if you're interested in creating Storybook stories for Relay components, I created a NPM package just for that: https://www.npmjs.com/package/use-relay-mock-environment

    It doesn't require adding the @relay-test-operation directive to your query, and instead relies only on resolving the String type (which is the default for all scalar properties). You can of course still add the @relay-test-operation directive and also extend the resolvers by providing customResolvers in the config. You can also extend the the String resolver as well, by providing extendStringResolver in the config.

    Feel free to review the source code here if you want to implement something similar: https://github.com/richardguerre/use-relay-mock-environment.

    Note: it's still in its early days, so some things might change, but would love some feedback!