React-apollo: MockedProvider + IntrospectionFragmentMatcher

Created on 14 Aug 2018  Β·  9Comments  Β·  Source: apollographql/react-apollo

Intended outcome:
I am able to use the MockedProvider, with no errors, with queries that contain union or interface types.

Actual outcome:
I've been following the great post here on how to use MockedProvider for "integration" tests of my <Query> components. I've been successful so far, but I ran into an issue when mocking a query that contains fragments on interface types.

 console.error node_modules/apollo-utilities/lib/bundle.umd.js:886
    You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.
         Apollo Client will not be able to able to accurately map fragments.To make this error go away, use the IntrospectionFragmentMatcher as described in the docs: https://www.apollographql.com/docs/react/recipes/fragment-matching.html

In my actual app, I create and provide the ApolloClient with an IntrospectionFragmentMatcher due to this issue warning. So, that fragment matcher is accessible, but, I don't know how to connect the IntrospectionFragmentMatcher with the MockedProvider from my tests.

How to reproduce the issue:

  • Write a query on an interface type
  • Follow the code samples from the Apollo docs on creating a MockedProvider that uses this query
  • Include typenames in the data / result and on the provider
  • Notice that while the test results are valid, the above error (Apollo Client will not be able to able to accurately map fragments...) is logged multiple times.

Some sample code

const myMock = {
  request: {
    query: QUERY_ON_INTERFACE_TYPES,
    variables: { /* if necessary */ },
  },
  result: {
    data: {
       /* Valid data matching the query, with __typenames */
       someField: {
          __typename: 'SomeField',
          value: 'Hello World',
       },
     },
  },
}

// Render or mount this
<MockedProvider mocks={[myMock]} addTypename>
  <MyComponent />
</MockedProvider>

Version
yarn list --pattern "apollo"
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
β”œβ”€ [email protected]
└─ [email protected]

  • [x] has-reproduction
  • [ ] feature
  • [ ] docs
  • [ ] blocking
  • [ ] good first issue
has-reproduction

Most helpful comment

Closing because this works now as of #2254 with a solution like below, creating a custom cache with the fragment matcher and passing it into the mocked provider

@kristiehowboutdat I can see that you can implement a custom cache - #2254
I have tried implementing something like:

mport {
  IntrospectionFragmentMatcher,
  InMemoryCache
} from "apollo-boost"

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: ...
})

const wrapper = mount(
  <MockedProvider mocks={ mocks } addTypename={ false } cache={ cache }>
    <Listings />
  </MockedProvider>
)

I've tried this solution.. but now my test is expecting a __typename in all responses. I've added the addTypename to false in the cache, and it throws an error saying that the response needs a __typename.

All 9 comments

I am in the same situation, did you ever find a solution to this?

@kristiehowboutdat I can see that you can implement a custom cache - https://github.com/apollographql/react-apollo/pull/2254

I have tried implementing something like:

mport {
  IntrospectionFragmentMatcher,
  InMemoryCache
} from "apollo-boost"

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: ...
})

const wrapper = mount(
  <MockedProvider mocks={ mocks } addTypename={ false } cache={ cache }>
    <Listings />
  </MockedProvider>
)

However I can't seem to get this to work, yet.

Looks like https://github.com/apollographql/react-apollo/pull/2254 hasn't been released. It's currently in vNext

@ellioseven thanks for sharing that! Currently I'm stubbing the console.error and console.warn for those tests to silence the copious warnings and errors from the fragment matcher, but this is obviously sub optimal. I'm only doing it after I used addTypename, added the __typenames to all the mock responses, and made sure I didn't have any missing field __typename warnings. So l am very anxious to get rid of those stubs and use a cache with the relevant fragment matcher like you showed above!

I think this can be closed now. You can now pass in a custom cache object into the mocked provider.

whats the purpose of fragmentMatcher.ts and IntrospectionFragmentMatcher in apollo-inmemory-cache? I have been reading through the source code but seems not very clear for me.

Closing because this works now as of #2254 with a solution like below, creating a custom cache with the fragment matcher and passing it into the mocked provider

@kristiehowboutdat I can see that you can implement a custom cache - #2254

I have tried implementing something like:

mport {
  IntrospectionFragmentMatcher,
  InMemoryCache
} from "apollo-boost"

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: ...
})

const wrapper = mount(
  <MockedProvider mocks={ mocks } addTypename={ false } cache={ cache }>
    <Listings />
  </MockedProvider>
)

Closing because this works now as of #2254 with a solution like below, creating a custom cache with the fragment matcher and passing it into the mocked provider

@kristiehowboutdat I can see that you can implement a custom cache - #2254
I have tried implementing something like:

mport {
  IntrospectionFragmentMatcher,
  InMemoryCache
} from "apollo-boost"

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: ...
})

const wrapper = mount(
  <MockedProvider mocks={ mocks } addTypename={ false } cache={ cache }>
    <Listings />
  </MockedProvider>
)

I've tried this solution.. but now my test is expecting a __typename in all responses. I've added the addTypename to false in the cache, and it throws an error saying that the response needs a __typename.

I have this same issue ^. Fixed with this comment: https://github.com/apollographql/react-apollo/issues/1747#issuecomment-553180150

Was this page helpful?
0 / 5 - 0 ratings