2017-08-15 93 views
6

Tôi đang sử dụng phản ứng-apollo để xây dựng một ứng dụng khách sử dụng API GraphQL, tuy nhiên, tôi rất khó khăn khi thử nghiệm. Những gì tôi muốn là giả lập máy chủ để tôi có thể dễ dàng kiểm tra ứng dụng mà không cần thực hiện cuộc gọi mạng.Làm thế nào để sử dụng dữ liệu giả lập với phản ứng-apollo cho các thử nghiệm

Tôi đã tìm thấy một số gợi ý về cách để thử server:

Nhưng không có thực sự là một ví dụ về cách sử dụng máy chủ này trong chế giễu thử nghiệm ứng dụng của tôi để tránh nhấn máy chủ.

Mục tiêu của tôi là để kiểm tra cài đặt tích hợp để khẳng định rằng ứng dụng được thực sự làm việc:

describe('Profile feature',() => { 
    beforeAll(() => { 
    store = setupStore(); 
    app = mount(
     <ApolloProvider store={store} client={apolloClient}> 
     <ConnectedRouter history={history}> 
      <App /> 
     </ConnectedRouter> 
     </ApolloProvider> 
    ); 
    }); 
}); 

Các cửa hàng đang sử dụng Redux và khách hàng đã được tạo ra như thế này:

const networkInterface = createNetworkInterface({ 
    uri: process.env.REACT_APP_API_URL 
}); 

export const apolloClient = new ApolloClient({ 
    networkInterface 
}); 

thế nào có thể Tôi sử dụng một máy chủ giả lập với graphql-công cụ ở đây thay vì API thực tế?

Trả lời

11

tôi thấy 2 cách khác nhau để tạo ra dữ liệu chế giễu cho các truy vấn apollo-client:

Đầu tiên là để sử dụng graphql-tools để tạo ra một máy chủ chế giễu dựa trên giản đồ phụ trợ của bạn, để kết nối máy chủ chế giễu này với các bài kiểm tra của bạn có thể tạo mockNetworkInterface như thế này:

const { mockServer } = require("graphql-tools"); 
const { print } = require("graphql/language/printer"); 


class MockNetworkInterface { 
    constructor(schema, mocks = {}) { 
    if (schema === undefined) { 
     throw new Error('Cannot create Mock Api without specifying a schema'); 
    } 
    this.mockServer = mockServer(schema, mocks); 
    } 

    query(request) { 
    return this.mockServer.query(print(request.query), request.variables); 
    } 
} 

Bạn có thể chuyển giao diện mạng này cho thành phần ApolloClient và nó sẽ hoạt động tốt!

Việc thiết lập này yêu cầu phải có lược đồ API của bạn được cập nhật trong ứng dụng khách của bạn, vì vậy tôi thấy nó hơi khó làm.

Một cách khác để làm điều này là sử dụng mockNetworkInterface cung cấp bởi apollo-client/test-utils

Bạn có thể sử dụng nó theo cách này:

import { UserMock, PublicationMock } from '../__mocks__/data'; 
import { mockNetworkInterface } from 'react-apollo/test-utils'; 
import ApolloClient from 'apollo-client'; 

// We will be using here the exact same Query defined in our components 
// We will provide a custom result or a custom error 
const GraphQLMocks = [ 
    { 
    request: { 
     query: UserProfileQuery, 
     variables: {} 
    }, 
    result: { 
     data: { 
     current_user: UserMock 
     } 
    } 
    } 
]; 

// To set it up we pass the mocks to the mockNetworkInterface 
const setupTests =() => { 
    const networkInterface = mockNetworkInterface.apply(null, GraphQLMocks); 
    const client = new ApolloClient({ networkInterface, addTypename: false }); 

    const wrapper = mount(
    <ApolloProvider client={client}> 
     <App /> 
    </ApolloProvider> 
); 

    return { 
    store, 
    wrapper 
    }; 
}; 

// Then the tests look like this 
describe('Profile feature',() => { 
    test('Profile view should render User details', async() => { 
    const { wrapper, store } = setupTests(); 

    const waitFor = createWaitForElement('.profile'); 

    await waitFor(wrapper); 

    const tag = wrapper.find('.profile-username'); 
    expect(tag.text()).toEqual(`${UserMock.first_name} ${UserMock.last_name}`); 
    }); 
}); 

Điều quan trọng là phải vượt qua addTypename: false đến ApolloClient dụ, nếu không bạn sẽ cần phải thêm __typename vào tất cả truy vấn của bạn theo cách thủ công.

Bạn có thể kiểm tra việc thi hành mockNetworkInterface đây: https://github.com/apollographql/apollo-test-utils/blob/master/src/mocks/mockNetworkInterface.ts

+1

Cảm ơn câu hỏi và câu trả lời của bạn! Điều này đặt tôi vào con đường bên phải sau nhiều giờ tìm kiếm! –

+0

Rất vui được trợ giúp, tôi đã cố gắng giải quyết vấn đề này trong một thời gian quá –

+0

@CarlosMartinez cái nào là phương pháp hay nhất được chấp nhận hoặc thư viện/tùy chọn được hỗ trợ tốt nhất? – arcom

6

Bạn cũng có thể sử dụng MockedProvider, mà làm cho nó thậm chí còn đơn giản hơn.

withPersons.js

import { gql, graphql } from 'react-apollo' 

export const PERSONS_QUERY = gql` 
    query personsQuery { 
    persons { 
     name 
     city 
    } 
    } 
` 

export const withPersons = graphql(PERSONS_QUERY) 

withPersons.test.js

/* eslint-disable react/prop-types */ 

import React, { Component } from 'react' 
import { MockedProvider } from 'react-apollo/test-utils' 

import { withPersons, PERSONS_QUERY } from '../withPersons' 

it('withPersons', (done) => { 
    const mockedData = { 
    persons: [ 
     { 
     name: 'John', 
     city: 'Liverpool', 
     }, 
     { 
     name: 'Frank', 
     city: 'San Diego', 
     }, 
    ], 
    } 

    const variables = { cache: false } 

    class Dummy extends Component { 
    componentDidMount() { 
     const { loading, persons } = this.props.data 
     expect(loading).toBe(true) 
     expect(persons).toBe(undefined) 
    } 

    componentWillReceiveProps(nextProps) { 
     const { loading, persons } = nextProps.data 

     expect(loading).toBe(false) 
     expect(persons).toEqual(mockedData.persons) 
     done() 
    } 

    render() { 
     return null 
    } 
    } 
    const DummyWithPersons = withPersons(Dummy) 
    mount(
    <MockedProvider 
     removeTypename 
     mocks={[ 
     { 
      request: { query: PERSONS_QUERY, variables }, 
      result: { data: mockedData } }, 
     ]} 
    > 
     <DummyWithPersons /> 
    </MockedProvider>, 
) 
}) 

Lưu ý: Bằng cách sử dụng một thành phần Dummy bạn chỉ cần kiểm tra graphql() Queries và đột biến của bạn và cách bạn đã cấu hình chúng (tùy chọn, đạo cụ, bỏ qua, các biến, vv) Vì vậy, bạn không gắn kết của bạn các thành phần React thực tế. Tốt hơn là kiểm tra những người trong trạng thái 'không kết nối' của họ.

+0

Vâng, bạn có thể, vấn đề duy nhất của tôi với MockedProvider là bạn không thể vượt qua addTypename: false cho máy khách apollo cơ bản, vì vậy các mocks của bạn sẽ cần phải bao gồm __typename ở mọi nơi. Họ sáp nhập một PR tôi mở ra để sửa chữa này https://github.com/apollographql/react-apollo/pull/1001 –

+0

Thực ra bạn đang sử dụng prop, lol, đẹp –

+0

Oh tôi hiểu, đó là sự ủng hộ của bạn! haha - Tôi chỉ nhận thấy nó hôm nay – devboell

Các vấn đề liên quan