Apollo-client: MockedProvider does not return mocks in a storybook.

Created on 27 Sep 2020  路  14Comments  路  Source: apollographql/apollo-client

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:

{
  error: undefined,
  loading: true,
  data: undefined
}

then it returns:

{
  error: undefined,
  loading: false,
  data: undefined
}

It does not return the mock I provided in my story

How to reproduce the issue:

Here is my story.tsx file

import React from 'react'
import { MockedProvider } from "@apollo/client/testing";
import LatestSells from '~/components/SalesPage/LatestSells'
import { LATEST_SELL_SIGNALS } from '~/common/queries'

export default {
  title: 'Sales page/latest sells',
}


const mocks = [
  {
    request: {
      query: LATEST_SELL_SIGNALS,
      variables: {},
    },
    result: {
      data: {
        dog: {
          name: "Douglas"
        }
      }
    }
  }
]

export const latest_sells = () => {
  return (
    <MockedProvider mocks={mocks} addTypename={false}>
      <LatestSells />
    </MockedProvider>
  )
}

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:

import React from 'react'
import { useQuery } from '@apollo/client'
import { LATEST_SELL_SIGNALS } from '~/common/queries'

const LatestSells = () => {
  const { loading, error, data } = useQuery(LATEST_SELL_SIGNALS)
  console.log(loading, error, data)
  return null
}

export default LatestSells

Even with the simplest possible setup, this does not work.

Lastly here is my query:

import { gql } from 'apollo-boost'

export const LATEST_SELL_SIGNALS = gql`
  query {
    latestSellSignalsList(orderBy: createdAt_DESC, first: 10) {
      items {
        name
        ticker
        boughtAt
        soldAt
      }
    }
  }
`

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

Most helpful comment

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 some of my apollo-link and apollo-boost imports to @apollo-client, but that did not affect anything.

All 14 comments

@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/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 some of my apollo-link and apollo-boost imports to @apollo-client, but that did not affect anything.

This behavior should be fixed/improved in @apollo/[email protected] (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/[email protected].
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/[email protected] 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/[email protected] and @apollo/[email protected] with installed the dependency of @wry/[email protected] 馃槥

sorry, any updates here?

Was this page helpful?
0 / 5 - 0 ratings