apollo-client: Breaking change from 3.0.2 to 3.1.0 [ MockedProvider ]

Intended outcome: Be able to mock a query using MockProvider

import { MockedProvider } from '@apollo/client/testing';
import { GET_TEACHERS_AND_ADMINS_OF_MY_DISTRICT_QUERY } from '../queries';

const mocks = [
  {
    request: {
      query: GET_TEACHERS_AND_ADMINS_OF_MY_DISTRICT_QUERY,
    },
    result: {
      loading: false,
      error: null,
      data: {
        teachersAndAdminsOfMyDistrict: [
          {
          [...]
...
      <MockedProvider mocks={mocks} addTypename={false}>
        <ComponentThatUsesTheQuery  />
      </MockedProvider>

Actual outcome:

After updating to 3.1.0 tests broke with:

    No more mocked responses for the query: {
      teachersAndAdminsOfMyDistrict {
      [...]

How to reproduce the issue: Described in the first section but if more info is needed I can add here.

Versions

  System:
    OS: Linux 5.4 Ubuntu 20.04.1 LTS (Focal Fossa)
  Binaries:
    Node: 10.19.0 - /usr/bin/node
    npm: 6.14.4 - /usr/bin/npm
  Browsers:
    Chrome: 84.0.4147.105
    Firefox: 79.0
  npmPackages:
    @apollo/client: ^3.1.0 => 3.1.0 
    apollo-upload-client: ^14.1.0 => 14.1.0 

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 16
  • Comments: 22 (3 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve resolved this with my post on this one

defaultOptions={{
                                watchQuery: { fetchPolicy: 'no-cache' },
                                query: { fetchPolicy: 'no-cache' },
                            }}

@tyagow as a work around, you can mock useQuery like so:

import * as Apollo from '@apollo/client';

jest.spyOn(Apollo, 'useQuery').mockImplementation(() => {
    return {
        loading: false,
        error: undefined,
        data: { MOCK_DATA },
        refetch: jest.fn()
    }
});

+1

We’re also experiencing this issue

I was having this issue on any 3.x.x version (my mocks have correct variables + __typenames and all that junk, this seemed like a legitimate bug with MockedProvider), upgrading to @apollo/client@3.3.0-beta.9 did NOT fix it for me, but upgrading to @apollo/client@3.3.0-beta.16 DID fix it for me.

edit: just wanted to say that this didn’t fix everything, still had some tests that were failing that definitely should pass (spent hours checking typenames + variables, 100% sure things are accurate). We had the most trouble with components that had 2 different queries running in the same file as well as queries with empty variables), it always got confused. ended up doing this in our jest

jest.mock('@apollo/client', () => ({
...jest.requireActual('@apollo/client'),
useQuery: (query, options) => jest.requireActual('@apollo/client').useQuery(query, {
  ...options,
  fetchPolicy: 'no-cache'
  })
})
)



basically just forcing no-cache for testing purposes

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!

The current apollo-client release is 3.3.5, and this seems to be fixed now.

Get this error - No more mocked responses for the query: mutation. Seems like MockedProvider broken or poorly documented.

I am actually unable to get MockedProvider working at all on any 3.x version of @apollo/client.

import { render } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import { MockedProvider } from '@apollo/client/testing'
import { Route, MemoryRouter } from 'react-router-dom'

...

describe('pipeline: none', () => {
  test('does not render environment section', async () => {
    const { getByText } = render(
      <MockedProvider
        mocks={[
          {
            request: {
              query: MARKETPLACE_OFFERING_QUERY,
              variables: {
                guid
              }
            },
            result: {
              data: {
                offering: { guid, name: 'mock offering' }
              }
            }
          }
        ]}
        addTypename={false}
      >
        <MemoryRouter initialEntries={['builder/123/456']}>
          <Route path="builder/:offering_guid/:plan_guid">
            <Builder />
          </Route>
        </MemoryRouter>
      </MockedProvider>
    )

    await new Promise(resolve => setTimeout(resolve, 0)) // wait for response

    expect(getByText('mock offering')).toBeInTheDocument()
  })
})

Leaving out this, the loading state is always true. With it the component is able to log out loading: true and then loading: false.

    await new Promise(resolve => setTimeout(resolve, 0)) // wait for response

The assertion fails, data is always undefined in the component even when loading: false from the useQuery.

I am running multiple queries, but the tests pass when I set the fetchPolicy to ‘no-cache’. I’m currently using the workaround @btferus5 suggested

In my case it was the same problem as described here: #6771

I added logging to my component that did the mutations and saw that the variables contained a field with an explicit undefined instead of omitting the field. So I just explicitly added undefined for the variable in my mock as well and it started working!

I found the issue to be the same as @Markus-ipse

The change in behavior appears to have been introduced here, by switching to a different deep equal function: https://github.com/apollographql/apollo-client/commit/2593f8f62fbe87e5a3eebb8b44e0f5482a75c3f7#diff-fab0a81f7f7c1e746fd7f86a7a1458c9 and https://github.com/apollographql/apollo-client/commit/26849a804a1be65071818285c9c31de8a8e4fb13 (cc: @benjamn)

The previous isEqual implementation ignored undefined object properties. Unfortunately, we were relying on that behavior so hundreds of our tests are now failing in 3.1.x.