I didn't know if I should open a new issue or if I should have commented on #4325
Intended outcome:
Writing a MockedProvider for a query only with @client directives should return data
Actual outcome:
No data is returned when the test is run.
How to reproduce the issue:
My test:
const mockLocal = () => [
{
request: {
query: GET_STATE,
variables: {},
},
result: {
data: {
renderType: 'default',
path: '',
staticContent: {
navigation: {
links: [
{to: '/article', text: 'Article'},
{to: '/home', text: 'Home'}
]
},
header: {
logo: ''
}
}
}
},
},
];
describe('<Html>', () => {
it('renders correctly', async () => {
const tree = renderer
.create(<MockedProvider mocks={mockLocal()} addTypename={false}><Router><Navigation/></Router></MockedProvider>)
.toJSON();
await wait(0);
expect(tree).toMatchSnapshot();
});
});
My query:
export const GET_STATE = gql`
{
renderType @client,
path @client,
staticContent @client {
navigation @client {
links @client {
to,
text
}
}
header @client {
logo
}
}
}
`;
The issue is that when I run the mock, and I console.log
in the component that uses the query, the result is an empty object instead of what I specified in result.data
Versions
System:
OS: Windows 10
Binaries:
Node: 11.4.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.13.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.4.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 42.17134.1.0
npmPackages:
apollo-client: ^2.5.1 => 2.5.1
react-apollo: ^2.5.1 => 2.5.1
Thanks @nicoladj77 - let's keep this as its own issue for now, but I'll be addressing this and https://github.com/apollographql/apollo-client/issues/4325 at the same time.
Is there any ETA on this? I am relying on @client
state for a few critical app components that I can't test right now :\
Don't want to put you in a hurry, I just want to know if I have to think about some alternative strategy for testing instead of waiting for a fix.
Hi @hwillson , @simonedavico - Any updates on this? Running into same problem as above.
Thanks!
+1
+1
This seems related to #4520
Hey everyone. I'm running into the same issues here. I've gotten around this by not including the custom resolvers (which makes the test suite noisy with the apollo warning about client directives without resolvers, but hey) in the MockedProvider in conjunction with using the render
and wait
functions from @testing-library/react-native
. Example:
const mocks = createMocks([{ isConnected: false, isPluggedIn: true }]);
const { container, getByText } = render({}, mocks);
await wait(() => {
expect(toJSON(container)).toMatchSnapshot();
});
Where the render
function is just a wrapper around creating the MockedProvider
in an easy way. Hope this helps until this issue is properly resolved.
+1
yeah same for me removing the resolvers from the mockProvider it works. Also make sure if you have __typename in the mocks.
```import { mount } from 'enzyme';
import { MockedProvider } from '@apollo/react-testing';
import React from 'react';
import { updateWrapper } from 'utils/testUtils';
import GET_CARDS_LIST_SORTING from './graphql/getCardListSorting.graphql';
import { en } from './translations';
import { TableHeadings } from '.';
describe('TableBody', () => {
const props = {
strings: en,
};
const mocks = [
{
request: {
query: GET_CARDS_LIST_SORTING,
},
result: {
data: {
cardsList: {
sorting: {
expiresIn: 'ASC',
__typename: 'CardsListSorting',
},
__typename: 'CardsList',
},
},
loading: false,
error: null,
},
},
];
it('matches snapshot', async () => {
const wrapper = mount(
);
await updateWrapper(wrapper);
console.log(wrapper.debug());
});
});
```
I'm also getting this.
Removing the resolvers being added to MockedProvider makes the mocked queries work. However i get the annoying "Found @client directives in a query but no ApolloClient resolvers were specified." console warning.
Furthermore I wonder how to best to test components that use local mutations resolvers if they're not being added?
Do you think this bug will be fixed? Or should i be testing local apollo things differently?
Thanks
I'm still facing this issue too.
Maybe we could do it with the temporary workaround for now, but wanted to ask the same question - if any attention is being paid to this issue, or if anything new came up about it.
If it helps, I could also provide my case, but it's really not that different compared to what is already discussed.
Bump, 1.5 years later after the original poster!
Facing the same issue...
Please note that MockedProvider
creates its own ApolloClient
instance behind the scenes, like this:
const {
mocks,
addTypename,
defaultOptions,
cache,
resolvers,
link
} = this.props;
const client = new ApolloClient({
cache: cache || new Cache({ addTypename }),
defaultOptions,
link: link || new MockLink(
mocks || [],
addTypename,
),
resolvers,
});
This means that if you're using Apollo Client 2.x local resolvers, or Apollo Client 3.x type/field policies, you have to tell the MockedProvider
component what you're going to do with @client
fields. Otherwise the ApolloClient
instance created behind the scenes doesn't know how handle things. In other words:
If using Apollo Client 2.x local resolvers, make sure your resolvers
object is passed into MockedProvider
:
<MockedProvider mocks={mocks} resolvers={resolvers} ...
If using Apollo Client 3.x type/field policies, make sure your configured cache
instance (with your typePolicies
) is passed into MockedProvider
:
<MockedProvider mocks={mocks} cache={cache} ...
For my scenario, i'm not testing a mutation or any update to the local state. The component i'm testing just simply fetches some data from local state. I'm not following how passing in local resolvers would help here. Can you provide an example here?
@chris-mo The mocked data you pass into MockedProvider
fakes out the data Apollo Client would get back through its Apollo Link chain. In other words it's faking out the data that would come back from making a request to a backend GraphQL API. @client
fields are virtual fields, meaning they are never sent through the Link chain, and their data never comes back through the Link chain. In other words, to be able to test @client
fields using MockedProvider
, you have to provide the data behind them in some other manner, since you can't provide that data using something like mocks
. There are different ways to do this, like providing your own resolvers
to return the mocked @client
data, or by using typePolicies
and a cache
instance to do the same thing. You can also write mock data for your @client
fields into the cache directly using something like cache.writeQuery()
, then make sure you pass that same cache
instance into MockedProvider
so it's used when your query runs.
@hwillson thanks! I actually gave this a shot last night, which got rid of the error message mentioned above, but i must have some incorrect syntax as the data returned still returns as undefined
let's say i have the following query
query {
state @client {
someObject {
someValue
}
}
}
The resolver i have for this but seems incorrect is
const resolvers = {
Query: {
state() {
return { ...}
}
}
}
EDIT: I got it to work, just had to edit my return obj. Thanks for the response @hwillson
Most helpful comment
I'm also getting this.
Removing the resolvers being added to MockedProvider makes the mocked queries work. However i get the annoying "Found @client directives in a query but no ApolloClient resolvers were specified." console warning.
Furthermore I wonder how to best to test components that use local mutations resolvers if they're not being added?
Do you think this bug will be fixed? Or should i be testing local apollo things differently?
Thanks