简体   繁体   中英

Using graphql-tools, apollo-link-schema, and react-hooks always returning undefined when mocking

I'm new to using GraphQL in React and have been moving a project from a REST API to a new GraphQL one. As part of this, I wanted to setup mock data to work on the application independent of the GQL API being completed. I've spent a bunch of time trying to follow the Apollo and GraphQL Tools docs but no matter what, I can't seem to get the mock resolvers to work properly. For context, I am using this in a NextJS/React app, and here's a minimum example of what I'm trying to do:

Setup App.js

import React from 'react';
import ApolloClient from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { SchemaLink } from 'apollo-link-schema';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { addMocksToSchema } from '@graphql-tools/mock';

export default function App() {
    const schema = makeExecutableSchema({typeDefs:`
        type Query {
            getPerson: Person!
        }
                
        type Person {
            name: String!
        }
    `});

    const mocks = {
        Query: () => ({
            getPerson: () => ({
                name: () => "Name"
            })
        })
    }

    addMocksToSchema({ mocks, schema });
    const link = new SchemaLink({ schema });
    const client = new ApolloClient({
        link,
        cache: new InMemoryCache(),
        connectToDevTools: true
    });

    return (
        <ApolloProvider client={client}>
            <Person />
        </ApolloProvider>
    )
}

Person.js

import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';

export default function Person() {
    const { loading, error, data } = useQuery(gql`
        query PersonQuery {
            getPerson {
                name
            }
        }
    `, {
        errorPolicy: 'all'
    });

    console.log(data);

    if (loading) return "Loading...";
    if (error) console.log(error);

    return (
        <h1>{data.getPerson.name}<h1>
    )
}

Looking at the console.log(error) result yields the error Cannot return null for non-nullable field Query.getPerson and making it a nullable field just returns { getPerson: null } of course. I've tried returning the resolver results as objects vs functions. Logging within the resolvers shows the Query part is being executed but nothing nested within that.

Am I setting something up incorrectly? I also tried not passing in custom mocks as suggested should be possible based on the graphql-tools docs, but to no avail. I also saw this issue from the apollo hooks GitHub that said the newest version of hooks broke the usage of addMocksToSchema, so I tried using the suggested 3.1.3 version but again no luck. Any help would be greatly appreciated!

You need to provide the mock to the client, not the plain schema.

const schemaWithMocks = addMocksToSchema({
  schema,
  mocks: {},
  preserveResolvers: false,
});

const client = new ApolloClient({
  // link: new SchemaLink({ schema }); < -- REPLACE THIS
  link: (new SchemaLink({ schema: schemaWithMocks }) as unknown) as ApolloLink, // https://github.com/apollographql/apollo-link/issues/1258
  cache: new InMemoryCache(),
  connectToDevTools: true,
});

Now console.log(data) prints {"getPerson": {"__typename": "Person", "name": "Name"}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM