使用Apollo 2.0,react-apollo和apollo-link-schema进行客户端查询模拟

时间:2018-02-13 03:08:47

标签: graphql apollo react-apollo apollo-client

我希望能够在客户端模拟一些查询,因此我不必提供GraphQL端点来处理我的React应用程序。

根据Apollo文档,看起来我应该使用apollo-link-schema。我试图按照这个例子,但在我的情况下,当我尝试访问包装组件中的查询结果时,我最终得到一个错误:Network error: Expected undefined to be a GraphQL schema.

有人可以帮我理解我在这里做错了吗?

这是一个完全包含的index.js示例来说明我的问题:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { SchemaLink } from "apollo-link-schema";
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloCache } from 'apollo-cache';

import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

import { makeExecutableSchema, addMockFunctionsToSchema, MockList } from 'graphql-tools';
const typeDefs = `
type Query {
  me: Person!
}

type Person {
    name: String!
}
`;
const schema = makeExecutableSchema({ typeDefs });
addMockFunctionsToSchema({ schema });

const schemaLink = new SchemaLink(schema);
const client = new ApolloClient({
    link: schemaLink,
    cache: new InMemoryCache()
});

class App extends Component {
  render() {
        if (this.props.query && this.props.query.loading) {
            return <div>Loading...</div>
        }

        if (this.props.query && this.props.query.error) {
            return <div>Error: {this.props.query.error.message}</div>
        }

        const person = this.props.query.me;
        return <div> {person.name} </div>
  }
}

const personQuery = gql`
    query PersonQuery {
        me {
            name
        }
    }
`;
App = graphql(personQuery, { name: 'query' })(App);

ReactDOM.render(
    <ApolloProvider client={client}>
        < App />
    </ApolloProvider>
    , document.getElementById('root')
);

2 个答案:

答案 0 :(得分:0)

更新:我可以使用来自react-apollo / test-utils的MockedProvider工作,但我想知道这是否是最好的前进方式。例如,据我所知,使用MockedProvider要求您为组件可能执行的每个查询设置完全匹配,而来自addMockFunctionsToSchema的{​​{1}}将允许您更灵活地自定义模拟,如the docs - 我只是希望能够做到这一点。

以下是使用MockedProvider的更新graphql-tools文件示例:

index.js

答案 1 :(得分:0)

我认为链接需要是其他东西

试试这个

import { ApolloLink, Observable } from 'apollo-link';

// ...
const link = new ApolloLink(operation => {
  const { query, operationName, variables } = operation;
  return new Observable(observer =>
    graphql(schema, print(query), null, null, variables, operationName)
      .then(result => {
        observer.next(result);
        observer.complete();
      })
      .catch(observer.error.bind(observer))
  );
});

在代码

的上下文中
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import { ApolloLink, Observable } from 'apollo-link';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { SchemaLink } from "apollo-link-schema";
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloCache } from 'apollo-cache';

import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

import { makeExecutableSchema, addMockFunctionsToSchema, MockList } from 'graphql-tools';
const typeDefs = `
type Query {
  me: Person!
}

type Person {
    name: String!
}
`;
const schema = makeExecutableSchema({ typeDefs });
addMockFunctionsToSchema({ schema });

const link = new ApolloLink(operation => {
  const { query, operationName, variables } = operation;
  return new Observable(observer =>
    graphql(schema, print(query), null, null, variables, operationName)
      .then(result => {
        observer.next(result);
        observer.complete();
      })
      .catch(observer.error.bind(observer))
  );
});
const client = new ApolloClient({
  link,
  cache: new InMemoryCache()
});

class App extends Component {
  render() {
    if (this.props.query && this.props.query.loading) {
      return <div>Loading...</div>
    }

    if (this.props.query && this.props.query.error) {
      return <div>Error: {this.props.query.error.message}</div>
    }

    const person = this.props.query.me;
    return <div> {person.name} </div>
  }
}

const personQuery = gql`
    query PersonQuery {
        me {
            name
        }
    }
`;
console.log(personQuery)
App = graphql(personQuery, { name: 'query' })(App);

ReactDOM.render(
  <ApolloProvider client={client}>
    < App />
  </ApolloProvider>
  , document.getElementById('root')
);