reactjs - Handling Apollo-wrapped descendants in unit tests that mount the React component -
i've been working apollojs in react (via react-apollo
) past several months , have learned number of tricks , challenges associated unit testing apollo-wrapped components.
when testing component directly wrapped apollo, export , test component before wrapped hoc returned graphql
. when testing component has apollo-wrapped component descendant, use enzyme's shallow
rendering whenever possible prevent descendant mounting. if full-dom rendering via mount
required, use mockedprovider
apollo's test utils descendants don't throw error trying access this.context
.
i have not found solution, however, following case: component apollo-wrapped descendants needs tested using full-dom rendering need make assertions involving component instance (e.g. state, instance methods, etc). avoid issues descendants, have wrap component in mocked provider, means assertions on wrapper
operating on mockedprovider
instance , not component want testing.
an example:
import { mount } 'enzyme' import { mockedprovider } 'react-apollo/lib/test-utils' // component has descendants wrapped in apollo , // need access `this.context` provided apollo provider import assignments 'app/components/assignments ... describe('<assignments />', function() { it('sets sorted assignments in initial state', function() { const assignments = [...] const wrapper = mount( <mockedprovider> <assignments assignments={assignments} /> </mockedprovider> ) // fail because wrapper of mockedprovider // instance, not assignments instance expect(wrapper.state('assignments')).to.eql([...]) }) })
i've tried find way via enzyme access component instance of child rather root, far can tell not supported. i've been trying find alternatives needing mockedprovider
in these tests have not found yet.
has figured out workaround sort of situation, or there different approach should taking deal nested apollo-wrapped components?
i've found solution problem. reason apollo-wrapped descendants of mounted components causing problems throw error when trying access this.context.client
. apollo's mockedprovider
creates apollo client (or optionally uses 1 provide) , makes available children via context.
turns out enzyme's mount
method allows specify component's context. had tried using before, didn't realize needed combine childcontexttypes context passed down mounted component's descendants. using these enzyme options avoids need use mockprovider
.
i'll demonstrate solution based off example provided in original question:
import react 'react' import { mount } 'enzyme' // apollo client configured in separate module // mocked network interface. won't go details on // here, happy provide more details if asks import mockedclient 'test/mocked_client' // component has descendants wrapped in apollo , // need access `this.context` provided apollo provider import assignments '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 } } ) // passes! expect(wrapper.state('assignments')).to.eql([...]) }) })
hopefully helps finds in similar situation!
Comments
Post a Comment