2017-09-13 7 views
1

저는 지난 수개월 동안 React (Rex)에서 ApolloJS로 작업 해 왔으며 단위 테스트와 관련된 많은 트릭과 과제를 배웠습니다. 래핑 된 구성 요소.React 구성 요소를 탑재 한 단위 테스트에서 Apollo로 감싸 진 자손 처리하기

Apollo로 직접 랩핑 된 구성 요소를 테스트 할 때, graphql에 의해 반환 된 HoC로 랩핑되기 전에 구성 요소를 내보내고 테스트합니다. 자손으로 Apollo 포장 된 구성 요소가있는 구성 요소를 테스트 할 때 가능할 때마다 Enzyme의 shallow 렌더링을 사용하여 해당 하위 구성 요소가 탑재되지 않도록합니다. mount을 통한 전체 DOM 렌더링이 필요하면 Apollo의 테스트 유틸리티에서 MockedProvider을 사용하여 자손이 this.context에 액세스하는 동안 오류를 발생시키지 않도록합니다.

다음과 같은 경우에는 해결책을 찾지 못했습니다. Apollo로 둘러싼 자손을 가진 구성 요소는 전체 DOM 렌더링을 사용하여 테스트해야하지만 구성 요소 인스턴스와 관련된 어설 션을 수행해야합니다 (예 : 상태, 인스턴스 방법 등). 자손과의 문제를 피하려면 조롱받은 공급자에게 구성 요소를 랩핑해야합니다. 즉, 인스턴스에서 작동하고 테스트하려는 구성 요소가 아닌 wrapper의 어설 션보다 우선합니다.

예 : 나는 오히려 지금까지 내가 말할 수있는 지원되지 않는 루트,보다 아이의 구성 요소 인스턴스에 액세스하는 효소를 통해 방법을 찾기 위해 노력했습니다

import { mount } from 'enzyme' 
import { MockedProvider } from 'react-apollo/lib/test-utils' 

// This component has descendants that are wrapped in Apollo and 
// thus need access to `this.context` provided by an Apollo provider 
import Assignments from 'app/components/assignments 

... 

describe('<Assignments />', function() { 
    it('sets sorted assignments in initial state', function() { 
    const assignments = [...] 

    const wrapper = mount(
     <MockedProvider> 
     <Assignments assignments={assignments} /> 
     </MockedProvider> 
    ) 

    // This will fail because the wrapper is of the MockedProvider 
    // instance, not the Assignments instance 
    expect(wrapper.state('assignments')).to.eql([...]) 
    }) 
}) 

. 나는 또한이 테스트에서 MockedProvider을 필요로하는 대안을 찾고자했지만 아직 아무것도 찾지 못했습니다.

이런 상황에 대한 해결책을 찾은 사람이 있습니까? 아니면 중첩 된 아폴로 포장 구성 요소를 다루기 위해 취해야 할 다른 접근 방법이 있습니까?

답변

1

문제점에 대한 해결책을 찾았습니다. 마운트 된 구성 요소의 Apollo가 감싸는 자손이 문제를 일으키는 이유는 this.context.client에 액세스 할 때 오류가 발생한다는 것입니다. Apollo의 MockedProvider은 Apollo 클라이언트를 생성하고 (선택적으로 사용자가 제공 한 것을 사용함) 컨텍스트를 통해 해당 자식을 사용할 수있게합니다.

효소의 mount 방법을 보면 성분의 context을 지정할 수 있습니다. 이전에이 방법을 사용해 보았지만 그 내용을 childContextTypes과 결합하여 해당 컨텍스트가 탑재 된 구성 요소의 자손에게 전달되어야 함을 알지 못했습니다. 이러한 효소 옵션을 사용하면 MockProvider을 사용할 필요가 없습니다.

import React from 'react' 
import { mount } from 'enzyme' 

// This is an Apollo client I configured in a separate module 
// with a mocked network interface. I won't go into details on 
// that here, but am happy to provide more details if someone asks 
import mockedClient from 'test/mocked_client' 

// This component has descendants that are wrapped in Apollo and 
// thus need access to `this.context` provided by an Apollo provider 
import Assignments from 'app/components/assignments 

... 

describe('<Assignments />', function() { 
    it('sets sorted assignments in initial state', function() { 
    const assignments = [...] 

    const wrapper = mount(
     <Assignments assignments={assignments} />, 
     { 
     context: { client: mockedClient }, 
     childContextTypes: { 
      client: React.PropTypes.object.isRequired 
     } 
     } 
    ) 

    // This now passes! 
    expect(wrapper.state('assignments')).to.eql([...]) 
    }) 
}) 

희망이 비슷한 상황에서 자신을 발견 한 사람을 도움 :

내 원래의 질문에 제공된 예 기반으로 솔루션을 보여거야!