Intended outcome:
I tried to test loading state
import {act, cleanup, render} from 'react-native-testing-library';
import { MockedProvider } from '@apollo/client/testing';
const {getByTestId} = render(
<MockedProvider mocks={[]} addTypename={false}>
{<ProductsScreen {...props} />}
);
await act(() => wait(0));
expect(getByTestId('ActivityIndicator')).not.toBe(null);
Actual outcome:
but it gives me an error
No more mocked responses for the query
Versions
System:
OS: macOS 10.15.3
Binaries:
Node: 10.18.1
Yarn: 1.21.1
npm: 6.13.6
Browsers:
Chrome: 83.0.4103.97
Safari: 13.0.5
npmPackages:
@apollo/client: ^3.0.0-rc.0 => 3.0.0-rc.0
you need to pass it the query, variables and expected result
I am attempting to upgrade to @apollo/client
with today's new release and having the same issue with tests for loading states.
+1
I have same issue on @apollo/client 3.0.1 version
it("should render loading spinner", () => {
const { getByTestId } = render(
<ApolloMockedProvider mocks={[]} addTypename={false}>
<SomeComponent />
</ApolloMockedProvider>,
);
expect(getByTestId("Spinner")).toBeVisible();
});
this test code is failed. and error message
Error: Uncaught [Error: No more mocked responses for the query: query xxxx
I saw the code related to this issue.
when I tested it by attaching @apolo/client to a project newly created with CRA, no issue occurred.
To be exact, I had to go through the error because I didn't have the mock query, but the test didn't fail.
I think Among the parts dealing with Observable, there seems to be a case with and without an error handling.
Same problem here... Trying to update to @apollo/client
and got tens of these "No more mocked responses" errors. Also in the simple loading state check.
There are times when the test fails and there are times when the error is thrown an error in this part.
FWIW,
In my opinion, when MockedProvider
receives mocks={[]}
, it should detect this as the intentional "loading" input, and just return null without throwing an error. That will keep the provider in the loading state indefinitely, and will save users the current headaches:
I believe the way to go is to add something like this at line 76 of mockLink.ts
(just a guess. I'm not sufficiently knowledgeable about the codebase):
if (!key) return null; // stay in the loading state without logging an error
This creates separation between cases where we want the error (a requested key does not exist in the mock) and when we do not want the error (no keys exist in the mock).
I have a workaround that appears to be working for me at the moment on @apollo/client v3.0.2
.
Using the OPs code as a starting point (NOT WORKING):
import {act, cleanup, render} from 'react-native-testing-library';
import { MockedProvider } from '@apollo/client/testing';
const {getByTestId} = render(
<MockedProvider mocks={[]} addTypename={false}>
{<ProductsScreen {...props} />}
);
await act(() => wait(0));
expect(getByTestId('ActivityIndicator')).not.toBe(null);
I recommend three changes:
No more mocked responses
error.MockedProvider
will update state after our expectation. To keep our test clean of React act()
warnings, we need to wrap that state change in act.All together, that looks like this (WORKAROUND SOLUTION):
import {act, cleanup, render} from 'react-native-testing-library';
import { MockedProvider } from '@apollo/client/testing';
import {myMock} from "./myMocks";
const {getByTestId} = render(
<MockedProvider mocks={[myMock]} addTypename={false}>
{<ProductsScreen {...props} />}
);
expect(getByTestId('ActivityIndicator')).not.toBe(null);
await act(() => wait(0));
So those shenanigans get my Apollo-loading tests passing stably in any order again. 馃檶
But it would be much nicer if a mock of []
would not throw a No more mocked responses
error to begin with. Then there would be no state change to worry about wrapping in act
, and no need to sneak in an expectation before the next tick, and testing the loading state would be nice and straightforward again. 馃榿
Hitting this while upgrading my project, it would be nice if there was a MockProvider mode that operated in a less strict mode, as it did prior to the update.
Same here, hundreds of our tests failed because of this issue. Please bring back the old behavior.
This behavior is even suggested in the documentation, though of course also giving the same Error:
https://www.apollographql.com/docs/react/development-testing/testing/#testing-loading-states
it('should render loading state initially', () => {
const component = renderer.create(
<MockedProvider mocks={[]}>
<Dog />
</MockedProvider>,
);
const tree = component.toJSON();
expect(tree.children).toContain('Loading...');
});
+1 I too have followed the documentation at https://www.apollographql.com/docs/react/development-testing/testing/#testing-loading-states. I am using react testing library. The same error about not more requests/responses is raised. This is really annoying...
For anyone still experiencing this bug (I am, even with everything up to date) I came up with an interim fix that doesn't patch anything.
Add a new LoadingApolloLink.js
somewhere in your project:
import { __extends } from 'tslib';
import { MockLink } from '@apollo/client/utilities/testing/mocking/mockLink';
var LoadingApolloLink = (function (_super) {
__extends(LoadingLink, _super);
function LoadingLink() {
var _this = _super.call(this) || this;
return _this;
}
LoadingLink.prototype.request = function (operation) {
return false;
};
return LoadingLink;
})(MockLink);
export { LoadingApolloLink };
Now use this link in your provider:
Note: I haven't actually tried this out in tests, only Storybook
<MockedProvider link={LoadingApolloLink}>
My story parameter setup looks like this:
apolloClient: {
link: new LoadingApolloLink()
}
Most helpful comment
Same here, hundreds of our tests failed because of this issue. Please bring back the old behavior.