I've been working with ApolloJS in React (via react-apollo) for the past several months and have learned a number of the tricks and challenges associated with unit testing Apollo-wrapped components.
When testing a component that is directly wrapped with Apollo, I export and test the component before it is wrapped with HoC returned by graphql. When testing a component that has an Apollo-wrapped component as a descendant, I use Enzyme's shallow rendering whenever possible to prevent that descendant from mounting. If full-DOM rendering via mount is required, I use a MockedProvider from Apollo's test utils so that the descendants don't throw an error trying to access this.context.
I have not found a solution, however, for the following case: a component with Apollo-wrapped descendants needs to be tested using full-DOM rendering but I also need to make assertions involving the component instance (e.g. state, instance methods, etc). To avoid issues with descendants, I have to wrap the component in a mocked provider, but that means than any assertions on the wrapper are operating on the MockedProvider instance and not the component I want to be testing.
An example:
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([...])
})
})
I've tried to find a way via Enzyme to access the component instance of a child rather than the root, which as far as I can tell is not supported. I've also been trying to find alternatives to needing the MockedProvider in these tests but have not found anything yet.
Has anyone figured out a workaround for this sort of situation, or is there a different approach I should be taking to deal with nested Apollo-wrapped components?