Intended outcome:
When making a request against a live GraphQL endpoint any undefined values in the variables object are removed from the payload.
When testing using the MockedProvider, the variables that were undefined remain in the request. This leads to the equality check failing (which it should).
The problem comes when you see the error message that Apollo throws.
The error message No more mocked responses were found etc uses JSON.stringify which excludes any values that were undefined. This behavior makes it tricky to debug because you're essentially seeing the exact mock you provided to the test.
Actual outcome:
How to reproduce the issue:
To reproduce:
In App.js note that the mutation has a value with undefined in the variables payload. Note that the mock in the test has the payload without the undefined value. This is the same request you would see get sent in the network tab.
Note that the error message excludes the undefined variable (see image) and that the query it's showing matches our mock exactly.

Versions
@apollo/[email protected]
Chrome: 84.0.4147.105
Jest: 25.2.3
One solution i can think of is using a replacer function on JSON.stringify to attach another message the those values that are present in the request but are not present in the mock.
eg:
function replacer(key, value) {
return typeof value === 'undefined' ? "SOME GOOD MESSAGE OR SOMETHING" : value;
}
if (!response || typeof responseIndex === 'undefined') {
this.onError(new Error(
`No more mocked responses for the query: ${print(
operation.query
)}, variables: ${JSON.stringify(operation.variables), replacer}`
));
return null;
}
Alternatively, have the mock request behave the same as a real world request and strip the undefined values prior to finding the mock.
Ran into this just now as well when migrating from 2 to 3, a large part of our apollo tests suddenly started failing and I just couldn't figure out what was going wrong. I think a rollback to the previous behavior (stripping undefined) would probably be desirable as right now it is a massive pain to debug and fix.
The problem is because MockLink is not using fast-json-stable-stringify to stringify variables and compare it.
Here is v2 MockLink equality check
Here is v3 MockLink equality check
fast-json-stable-stringify basically strips undefined values.
I'm interested is this a bug in v3 or intentional change?
I cannot find breaking change in Changelog for MockedProvider or MockLink.
it looks like I also have this issue 鈽濓笍
@benjamn looks like MockLink is using your new @wry/equality package but it's a regression for a) not stripping undefined keys (kudos vedrani ^) and also b) not .toJSON-ifying both sides (i.e. a feature of apollo-client is that you can pass in variables that aren't strictly JSON, but it will .toJSON them, i.e. during something like class MyDateUserType into "2020-08-23" by implicitly calling MyDateUserType.toJSON during the previous fast-json-stable-stringify).
This behavior should be fixed/improved in @apollo/[email protected] (just published to npm), thanks to #7108. Please give it another try after updating!
Thanks! I'll update and try it out.
Tell me is I'm wrong but this regression seems to remain in @apollo/[email protected] ?
Most helpful comment
The problem is because MockLink is not using fast-json-stable-stringify to stringify variables and compare it.
Here is v2 MockLink equality check
Here is v3 MockLink equality check
fast-json-stable-stringifybasically strips undefined values.I'm interested is this a bug in v3 or intentional change?
I cannot find breaking change in Changelog for MockedProvider or MockLink.