apollo-feature-requests icon indicating copy to clipboard operation
apollo-feature-requests copied to clipboard

Ability to use wildcards in mocks / mock a range of requests

Open dominik-fielmann opened this issue 4 years ago • 8 comments

Motivation

I am currently developing a prototype / proof of concept for an app where the user searches for an id and gets a view of the product. I want to prepare the GraphQL integration, but for now I want to mock all requests to the backend and return default dummy data to show to the user.

The problem

To use the MockedProvider to mock away the graphql backend, I have to specify exactly which variables the query will be called with. But I have no way to anticipate what the user will try to search for.

Feature Request

Make it possible to use wildcards in mocks or otherwise leave open a part of the query, so it matches regardless of a variable value.

Example / Proposed feature

This matches only one very specific query:

const mocks = [
  {
    request: {
      query: GET_ARTICLE,
      variables: { articleNumber: "123456" }
    },
    result: {
      data: { article: testArticle } 
    }
  }
];

Something like this could match all queries to GET_ARTICLE and always return the same result:

const mocks = [
  {
    request: {
      query: GET_ARTICLE
    },
    result: {
      data: { article: testArticle } 
    }
  }
];

Alternatively:

    request: {
      query: GET_ARTICLE
      variables: { articleNumber: ANY_VALUE }
    }

where ANY_VALUE would be a wildcard constant that Apollo recognises.

dominik-fielmann avatar Jan 17 '20 09:01 dominik-fielmann

I prefer to avoid MockedProvider entirely and instead go with the approach outlined here: https://medium.com/free-code-camp/a-new-approach-to-mocking-graphql-data-1ef49de3d491

This is the approach I use in all my client-side tests. It automatically provides mock data of the correct type, but you can still specify your own mock data if you wish. You can also choose to only provide some mock data, and allow the rest of the query data to be mocked automatically. The query arguments are provided to your mock function in the second parameter, so you can choose to return different mock data depending on the query arguments (or just ignore the variables entirely)

This article was also helpful: https://www.robinwieruch.de/graphql-server-mock-apollo-client

The downside of this approach is that apollo-link-schema has a fairly large bundle size, which is why it's usually recommended not to use it in your app. But if you don't mind a large bundle size, I think the apollo-link-schema approach is much more flexible than the MockedProvider approach.

dylanwulf avatar Jan 17 '20 16:01 dylanwulf

Released this package which supports wildcards in mocks and a bunch of other nice functionality to help writing tests: https://github.com/insidewhy/wildcard-mock-link

Is documented/tested.

insidewhy avatar Apr 23 '20 05:04 insidewhy

👍 on this

richardwu avatar Apr 03 '21 01:04 richardwu

@richardwu you should use reactions instead of comments saying +1 which notify all thread watchers. At any rate wildcard-mock-link already supports this together with all other features of the mock link.

insidewhy avatar Apr 03 '21 05:04 insidewhy

@insidewhy wildcard-mock-link does not support jest act, nor does it support Apollo Client Addon for Storybook. Having this functionality inside the apollo MockedProvider would greatly speed up our tests and improve our stories.

Please do not dismiss this use case as solved because there is a workaround.

david-morris avatar Dec 17 '21 16:12 david-morris

does not support jest act

It does, you can even pass act as a constructor argument to avoid having to use it manually if you want.

nor does it support Apollo Client Addon for Storybook

Could you give some details on this?

insidewhy avatar Dec 18 '21 03:12 insidewhy

@insidewhy

you can even pass act as a constructor argument

Wow, thank you. I can't believe I missed this after how many times I read the documentation. You just saved my team and tests a lot of time.

Apollo Client Addon details

https://storybook.js.org/addons/storybook-addon-apollo-client

I was hoping to use that as a way of showing parameters of mocked mutations in the stories. I think I can probably hack around it by processing the request callback of my mocks.

david-morris avatar Dec 19 '21 12:12 david-morris

@insidewhy

you can even pass act as a constructor argument

Wow, thank you. I can't believe I missed this after how many times I read the documentation. You just saved my team and tests a lot of time.

Apollo Client Addon details

https://storybook.js.org/addons/storybook-addon-apollo-client

I was hoping to use that as a way of showing parameters of mocked mutations in the stories. I think I can probably hack around it by processing the request callback of my mocks.

Thanks for the link to the addon! I combined it with the Play function to specifically enter data for the variables used on the mock and tell that as a distinct story: https://storybook.js.org/docs/react/writing-stories/play-function.

riezebosch avatar Jan 18 '22 09:01 riezebosch

  • https://github.com/apollographql/apollo-client/pull/6701

RobinTail avatar Jan 18 '24 08:01 RobinTail

Thanks for the nudge @RobinTail!

That change will be coming in the next minor 3.9.0 which should release within the next couple weeks. As such, I'm going to go ahead and close out this issue. Feel free to open a new feature request if you need further assistance. Looking forward to getting this one out!

jerelmiller avatar Jan 18 '24 17:01 jerelmiller

unfortunately this solution only works for 1 call, has anyone else tested this?

ARkrOSClou avatar Jan 27 '24 20:01 ARkrOSClou

Hey @ARkrOSClou 👋

I think you'll find https://github.com/apollographql/apollo-client/pull/11178 useful, which will be released in 3.9 along with the change to dynamically match variables. You can set a maxUsageCount to tell MockedProvider to reuse a mock as many times as you need to.

Check out the preview docs if you'd like to try this feature out in 3.9.0-rc.1 before our public release of 3.9 🙂

jerelmiller avatar Jan 28 '24 04:01 jerelmiller

Hey @ARkrOSClou 👋

I think you'll find apollographql/apollo-client#11178 useful, which will be released in 3.9 along with the change to dynamically match variables. You can set a maxUsageCount to tell MockedProvider to reuse a mock as many times as you need to.

Check out the preview docs if you'd like to try this feature out in 3.9.0-rc.1 before our public release of 3.9 🙂

Hey @jerelmiller!

~Not sure if I understand it correctly, but this code throws errors on all subsequent calls:~ Sorry for my ☝️ message, I found a bug in my implementation.

This code works as expected, it accepts any variables for the first and all the subsequent calls!

const mocks = [ {
    request: {
      query: ...,
    },
    maxUsageCount: Number.POSITIVE_INFINITY,
    variableMatcher: () => true,
    result: { ... }
} ]

// ... 
<MockedProvider mocks={mocks}>
// ...

ferrata avatar May 17 '24 21:05 ferrata