Open stolinski opened 6 years ago
I'm having the same issue and thought I'd add some extra details to the problem:
From my understanding you usually test your Apollo/React code with MockedProvider
. The problem is this is just testing your React/Apollo implementation. What I want to test is my apollo-link-state
logic in isolation (not coupled to my React components).
I figured I can use the ApolloClient
API to directly access the cache, then run queries/mutations to test my typeDefs
, reducers
, and defaults
for my local state management.
For instance, to test your typeDefs
you can do something like:
describe("typeDefs", () => {
describe("Modal", () => {
it("has an `id` field", () => {
const id = 'Modal:1';
const fragment = gql`
fragment getModal on Modal @client {
id
}
`;
const modal = cache.readFragment({ fragment, id });
expect(modal.id).toBeDefined();
});
});
});
The problem is you can't test your reducers because the cache API doesn't provide any method to run mutation
, only fragment
or query
(such as with writeQuery
and writeFragment
).
I haven't figured out any way around this, or a suitable workaround for testing in the meantime. It seems odd there isn't a solution for this, so perhaps I'm doing something wrong? How do people usually test their apollo-link-state
code?
I was having the same issue. Here's how I solved it (using Jest):
ApolloClient
with just the ApolloLink
that's created from withClientState
in apollo-link-state
readQuery
and mutate
directly on that clientPromise
returned by mutate
readQuery
// clientState.test.js
import React, { Component } from 'react'
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { withClientState } from 'apollo-link-state'
import gql from 'graphql-tag'
import { queryCurrentTeamId } from '../queries'
import { resolvers, defaults } from '../clientState'
const SET_CURRENT_TEAM_ID = gql`
mutation SetCurrentTeamId($id: Integer!) {
setCurrentTeamId(id: $id) @client
}
`
const cache = new InMemoryCache()
const link = withClientState({
resolvers,
defaults: {...defaults, currentTeamId: 53},
cache
})
const client = new ApolloClient({
link,
cache
})
it('queries currentTeamId', () => {
expect(client.readQuery({query: queryCurrentTeamId})).toEqual(
expect.objectContaining({
currentTeamId: 53
})
)
})
it('mutates currentTeamId', (done) => {
client.mutate({mutation: SET_CURRENT_TEAM_ID, variables:{id: 999}})
.then(result => {
expect(result).toEqual(
expect.objectContaining({
data: {
setCurrentTeamId: null
},
errors: undefined
})
)
expect(client.readQuery({query: queryCurrentTeamId})).toEqual(
expect.objectContaining({
currentTeamId: 999
})
)
done()
})
})
// clientState/index.js
import { queryCurrentTeamId } from '../queries'
export const defaults = {
currentTeamId: null
}
export const resolvers = {
Mutation: {
setCurrentTeamId: (_obj, args, context, _info) => {
const { id } = args
const { cache } = context
cache.writeQuery({query: queryCurrentTeamId, data: { currentTeamId: id }})
return null
}
},
}
// queries/index.js
import gql from 'graphql-tag'
// ...
export const queryCurrentTeamId = gql`
query {
currentTeamId @client
}
`
// ...
There seems to be a void in the documentation on testing with Apollo Link State. It would be helpful to have an example of how to test local state mutations using direct manipulation via ApolloConsumer or even how to setup a Mock Provider with default local state.