2015-09-24 17 views
20

Tôi đang thử nghiệm với React + Relay + Graphql những ngày này. Thật không may, tôi không thể tìm thấy bất kỳ cách dễ dàng và thuận tiện để kiểm tra thành phần React được bao bọc bởi Relay Container.Thử nghiệm chiến lược trên Relay + React

Về cơ bản, tôi muốn đạt được những mục tiêu này cùng TDD,

  1. Render một container và kiểm tra nội dung của nó,
  2. biến đổi và kiểm tra những thay đổi của mình vào nội dung.

So với React + Flux, React + Relay giống hộp đen hơn, hoặc khai báo.

Tôi có thể thấy mọi người giả lập Relay.createContainer để bỏ qua Relay và chỉ thử nghiệm React Component. Nó rời khỏi phần Relay phát hiện và không có cách nào để lái xe phần này bằng cách thử nghiệm. https://github.com/facebook/relay/issues/161

Ngoài ra, tôi đọc qua các trường hợp thử nghiệm của Rơ le và thực sự rất tẻ nhạt để hiển thị vùng chứa giả. https://github.com/facebook/relay/blob/master/src/tools/mocks/RelayTestUtils.js

Tôi sẽ rất biết ơn nếu bạn có thể chia sẻ giải pháp cho bạn.

Cảm ơn!

+0

Tôi nghĩ rằng đây là ý tưởng tốt nhất: http://stackoverflow.com/questions/38327428/integration-testing- của-relay-container-với-jest-chống-một-working-graphql-back –

Trả lời

12

Tôi đã cố gắng kiểm tra các bộ chứa Relay giống như các thành phần trong ứng dụng Flux. Cụ thể, tôi muốn đảm bảo rằng chúng hiển thị đúng nội dung cho một trạng thái và đạo cụ nhất định và chúng gọi các phương thức để thay đổi dữ liệu ở những nơi thích hợp; trong thông tin này, đây là cuộc gọi tới người tạo hành động, trong Rơ-le, hãy gọi tới số Relay.Store.update hoặc this.props.relay.setVariables.

Nỗ lực đầu tiên của tôi là tạo đối tượng RelayTestUtil với phương thức renderContainerIntoDocument. Tôi dựa rất nhiều vào https://github.com/facebook/relay/blob/master/src/tools/mocks/RelayTestUtils.js, https://github.com/facebook/relay/blob/master/src/legacy/store/mocks/GraphQLStoreQueryResolver.js và kiểm tra Vùng chứa chuyển tiếp. Điều này sử dụng chế nhạo rất tối thiểu và rất tuyệt vời để thử nghiệm việc kết xuất vùng chứa nhưng hoàn toàn vô dụng khi kiểm tra các thay đổi dữ liệu. Cố gắng theo dõi các cuộc gọi đến Relay.Store.updatethis.props.relay.setVariables hoặc để thay đổi dữ liệu giả tạo, trở nên rắc rối hơn so với giá trị.

Tôi đã quyết định thêm __mocks__\react-relay.js để hoàn toàn thử chuyển tiếp và sử dụng phiên bản đơn giản của RelayTestUtils.renderContainerIntoDocument để đưa thuộc tính Relay vào vùng chứa. Tôi không hoàn toàn hài lòng với giải pháp này, nhưng có vẻ như nó đang hoạt động.

__mocks__\react-relay.js:

var Relay = require.requireActual('react-relay'); 
var React = require('react'); 

module.exports = { 
    QL: Relay.QL, 
    Mutation: Relay.Mutation, 
    Route: Relay.Route, 
    Store: { 
    update: jest.genMockFn() 
    }, 
    createContainer: (component, containerSpec) => { 
    const fragments = containerSpec.fragments || {}; 

    // mock the static container methods 
    Object.assign(component, { getFragment: (fragmentName) => fragments[fragmentName] }); 

    return component; 
    } 
}; 

RelayTestUtils.js:

const React = require('react'); 
const ReactDOM = require('react-dom'); 


const RelayTestUtils = { 
    renderContainerIntoDocument(containerElement, relayOptions) { 
    relayOptions = relayOptions || {}; 

    const relaySpec = { 
     forceFetch: jest.genMockFn(), 
     getPendingTransactions: jest.genMockFn().mockImplementation(() => relayOptions.pendingTransactions), 
     hasOptimisticUpdate: jest.genMockFn().mockImplementation(() => relayOptions.hasOptimisticUpdate), 
     route: relayOptions.route || { name: 'MockRoute', path: '/mock' }, 
     setVariables: jest.genMockFn(), 
     variables: relayOptions.variables || {} 
    }; 

    return ReactDOM.render(
     React.cloneElement(containerElement, { relay: relaySpec }), 
     document.createElement('div') 
    ); 
    } 
}; 

export default RelayTestUtils; 

thử nghiệm giống như thế này, nơi fragmentData phù hợp với hình dạng của các phản ứng GraphQL:

it('changes items',() => { 
    const myContainer = RelayTestUtils.renderContainerIntoDocument(
    <MyContainer { ...fragmentData }/>, 
    { variables: { itemId: 'asdf' } } 
); 
    myContainer.changeItem(); 
    expect(myContainer.props.relay.setVariables).toBeCalled(); 
}); 
+1

Nó cũng sẽ không thể chỉ 'giả' ra khỏi lớp mạng? Vì vậy, tương tự như pretender (https://github.com/pretenderjs/pretender) relay thực sự có thể gửi ra các truy vấn nhưng sau đó thay vì nói chuyện với một máy chủ nó chỉ được lấy lại dữ liệu giả. – Markus

+1

@agrauch, bạn có thể cung cấp một ví dụ về repo không? –

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