Open MarkLyck opened 4 years ago
@MarkLyck Are you actually still using apollo-boost
, apollo-link
, apollo-link-batch-http
, etc? For the link imports, HttpLink
should be imported directly from @apollo/client
, and the other links can be imported from @apollo/client/link/core
, @apollo/client/link/batch-http
, @apollo/client/link/context
, and/or @apollo/client/link/error
.
We even have a codemod to help automate the conversion of imports: https://github.com/apollographql/apollo-client/tree/main/scripts/codemods/ac2-to-ac3
I have the same issue with @apollo/client/testing
I have the mocks but the request data comes undefined.
I find this a strange user-behaviour, but I figured it out.
I was testing it with dummy data this entire time because I just wanted to see the data return "something".
However, apparently if you give the mockProvider a mock that doesn't 100% match the expected schema, it will just give up and return undefined
with no error, warning or anything.
When I replaced my dummy data, with a data matching the exact schema of my request it works corrrectly.
Wasted a lot of time on this detail. Please consider adding an error or warning if the mock doesn't match the expected return, if this is the intended behaviour.
P.S. I also tried setting my apollo-link and apollo-boost imports to @apollo-client, but that did not affect anything.
This behavior should be fixed/improved in @apollo/client@3.3.0-beta.9
(just published to npm), thanks to #7108. Please give it another try after updating!
Hi @benjamn. I just tried with "@apollo/client": "^3.3.0-beta.9" but had the same problem @MarkLyck said before. Got it working after setting the result data exactly like the schema of my request.
@benjamn Can second that. This behavior is still the same with @apollo/client@3.3.0-beta.14
.
It's actually worse, because apollo doesn't even throw an error anymore when a mock is not found/matched.
I am having this issue right now and it's very difficult to debug what I need to do to return my data. If I change my mocks to use a function to return the result, I can see it's running.
{
request: {
query: GET_HOUSE_BY_ID,
variables: {
id: PROPERTY_ID,
},
},
result: () => {
console.log('This runs in my tests but data is undefined')
return {
data: {
houses_by_pk: house,
}
}
}
},
Having the same issue. As a workaround you may set the fetchPolicy == "no-cache" in the useQuery options:
const { loading, error, data } = useQuery(LATEST_SELL_SIGNALS, {fetchPolicy: "no-cache"})
Getting same issue with @apollo/client@3.3.4
even if mocked data matches exactly query inside component.
Also found that if the nested mock response does not include __typename
, it will also be removed silently.
I think this may be related.
Regarding addTypename
behaviour.
With the following query:
const SIMPLE_QUERY = gql`
{
a {
b
}
}
`;
and testing the following hook:
const useSimpleHook = () => {
const { data, loading, error } = useQuery(SOME_QUERY);
return { data, loading, error };
};
when addTypename
is set to false
the hook returns the error:
ApolloError: No more mocked responses for the query: {
a {
b
__typename
}
}
I thought from this explanation in the docs that setting addTypename
to false
would make the __typename
property not appear. Instead when setting addTypename
to true
the test passes successfully and the mock data is returned.
I should also say that the majority of issues during testing had to do with the cache not being reset on every test.
Getting the same issue with @apollo/client@3.3.6
and @apollo/client@3.4.0-beta.4
with installed the dependency of @wry/equality@0.3.1
😞
sorry, any updates here?
I'm also running into issues getting MockedProvider to do anything. I've looked at the queries for some time and it's always just returning undefined
for data with no logging as to what might be wrong with my query. This is with @apollo/client ^3.2.5.
It is like @MarkLyck suggested. If your schema-Mock does not match what the MockedProvider
is expecting, it does return undefined. I tried using one of the responses from the browser to generate a Mock and it worked!
Having the same issue. As a workaround you may set the fetchPolicy == "no-cache" in the useQuery options:
const { loading, error, data } = useQuery(LATEST_SELL_SIGNALS, {fetchPolicy: "no-cache"})
I had this exact issue which this fixes, but I don't want to have to refetch my user both on the server and then again in the component, is there another work around for this?
Edit: After a lot of searching there's a work around adding defaultOptions
parameter to the mocked provider!
<MockedProvider
mocks={mocks}
addTypename={false}
defaultOptions={{ watchQuery: { fetchPolicy: 'no-cache' } }}
>
v3.3.11, the same problem. None of the solutions mentioned above helped. Did someone manage to solve this problem differently?
@marcin-piechaczek can you provide a testable Version of what you're working with? I'd love to take a look.
Hi @bastianwegge, thanks for the reply. I noticed that this problem must be somewhere on my side because I cannot reproduce this problem on a mocked project. I will double-check my config and let you know.
@benjamn I guess this issue can be closed then, the original issue-creator was satisfied in September 2020 (https://github.com/apollographql/apollo-client/issues/7081#issuecomment-700923092)
In my case, the SSR turned out to be the problem. I fetch the data on the server-side, then read it from the client-side cache and between the data was undefined. I solved this problem by adding a loading state that satisfies mockProvider.
Stack: Nextjs + apollo + storybook (stories with apollo hook useQuery was undefined). Add loading state to the component and make sure that fetched data is equal to the mocked.
Same issue here. A mock call had bit-rotted and broke a story due to a missing query in an updated GraphQL operation. I updated @apollo/client to latest (3.3.13), but still no sensible error message: just loading false, error undefined, data undefined. This is super unhelpful--an error warning of invalid mocks would be much more useful here.
Not sure if this is the issue others had, but after hours and hours I finally figured out our issue.
Our mocks were not providing arrays (that were typed as optional), by just adding empty arrays for those properties in the mocks, finally the response is as expected.
a) this seems like a bug b) to echo everyone else, some minimal error message would've been sooooooo helpful here
EDIT: Turns out any prop missing (incl any optional props) is causing our data to be undefined. Our stop gap is to use this type
type RecursiveRequired<T> = T extends Object ? {
[Property in keyof T]-?: RecursiveRequired<T[Property]>;
} : T
applied to our fragments to enforce that all props are present
I have the same issue with "@apollo/client": "^3.3.15",
@ben-gooding-sky Thanks a lot! I spent too much time on this issue. Your solution works great.
I have added defaultOptions={{ watchQuery: { fetchPolicy: 'no-cache' } }}
to the MockedProvider
and it works. Thank you.
While fetchPolicy: 'no-cache'
will work for most people, I was specifically trying to unit test the caching behavior of my app, so I couldn't use that fix.
Instead, I took the advice from https://levelup.gitconnected.com/gotchas-using-react-apollo-mockprovider-ec2a22a07e76:
Inject InMemoryCache to show the error message
Using that technique, I was able to fix some subtle problems in my mocked responses which had been breaking my test, and I no longer needed to rely on fetchPolicy: 'no-cache'
.
@tarehart Thanks for this link. It's very helpful. I have added __typename to the mocks as I use fragments in queries. It's not obvious and there is no mention of this in the docs (or I haven't found).
I've tried everything on this list, but no success still.
Testing on React Native.
While
fetchPolicy: 'no-cache'
will work for most people, I was specifically trying to unit test the caching behavior of my app, so I couldn't use that fix.Instead, I took the advice from https://levelup.gitconnected.com/gotchas-using-react-apollo-mockprovider-ec2a22a07e76:
Inject InMemoryCache to show the error message
Using that technique, I was able to fix some subtle problems in my mocked responses which had been breaking my test, and I no longer needed to rely on
fetchPolicy: 'no-cache'
.
Solution Number 3 of your link is what fixed it for me.
Honestly no idea why I have to do these extra steps since it seems like this should be a part of the processes that the MockedProvider
takes, buuuuu...t whatever.
Dilemma deleted.
This is something which needs to be improved. For example, another scenario is when the MockedQuery should contain variables.
This returns undefined:
const mockedQuery = {
request: {
query: MY_QUERY,
variables: {
example: "someString",
},
},
.
.
.
}
but this works fine:
const mockedQuery = {
request: {
query: MY_QUERY,
variables: {
example: "",
},
},
.
.
.
}
This is ridiculous that "variables" values may cause that the whole data in a test is undefined.
Please throw an error when mismatched mock shape causes NO MOCK DATA AT ALL to be supplied. That seems like an important requirement for a test component.
tried every solution but it does not work
In my case I had to wait so the request could resolve
import { MockedProvider } from '@apollo/client/testing';
import { act, render, screen } from '@testing-library/react';
beforeEach(async () => {
render(...)
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
});
the solution for me without changing cache type on the react component, was to add __typename
when needed (where we had a fragment) on the mocks
I've added __typename field to my mock entities and it works, thanks all!
Please consider adding an error or warning if the mock doesn't match the expected return, if this is the intended behaviour.
Indeed throwing, an ideally meaningful, error will be the safest thing to do
Just tagging this RFC as it's related https://github.com/apollographql/apollo-client/issues/9738
Was facing the same issue. I am using @testing-library/react
for testing.
The trick is to wrap render
inside act(...)
and await
on it.
import { act, render, screen } from '@testing-library/react';
import { MockedProvider, MockedResponse } from '@apollo/client/testing';
const mocks: MockedResponse[] = [
{
request: { ... },
response: { ... },
}
]
describe('Test cases', () => {
it('One of the test case', async () => {
await act(async () => { <<======= THIS LINE
render(
<MockedProvider mocks={mocks} addTypename={false}>
<MyComponent />
</MockedProvider>
);
});
// Assert on any condition.
expect(screen.getByTestId(...)).not.toBeNull();
});
});
I have the same issue (not only in a storybook, but just in my tests). Could anyone from core team pay attention to this issue? It's been 3 years since the bug appeared
For me works two solutions:
defaultOptions={{ watchQuery: { fetchPolicy: 'no-cache' } }}
to the MockProvider cache={
new InMemoryCache({
possibleTypes: {
YourInterface: ['possibleTypeOne', 'possibleTypeTwo],
},
})
}
Intended outcome: The MockedProvider should work in a storybook environment and return the mock request provided to the MockProvider as per the docs: https://www.apollographql.com/docs/react/api/react/testing/#mockedprovider
Actual outcome: When running a story with MockedProvider, the useQuery hook returns:
then it returns:
It does not return the mock I provided in my story
How to reproduce the issue:
Here is my story.tsx file
I tried both with and without
addTypename={false}
I made my component as simple as possible to troubleshoot, but it doesn't work even when simplified down to the smallest possible react component.
component:
Even with the simplest possible setup, this does not work.
Lastly here is my query:
I've doubled checked that the query console logs correctly and the same in both the story and the actual component.
Versions System: OS: macOS 10.15.6 Binaries: Node: 14.4.0 - /usr/local/bin/node Yarn: 1.22.4 - /usr/local/bin/yarn npm: 6.14.5 - /usr/local/bin/npm Browsers: Chrome: 85.0.4183.121 Firefox: 81.0 Safari: 14.0 npmPackages: @apollo/client: ^3.2.1 => 3.2.1 apollo-boost: ^0.4.9 => 0.4.9 apollo-link: ^1.2.14 => 1.2.14 apollo-link-batch-http: ^1.2.14 => 1.2.14 apollo-link-context: ^1.0.20 => 1.0.20 apollo-link-error: ^1.1.13 => 1.1.13 apollo-utilities: ^1.3.4 => 1.3.4