Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
dominik-fielmann opened this issue Jan 17, 2020 · 13 comments
Closed

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

dominik-fielmann opened this issue Jan 17, 2020 · 13 comments
Labels
🧪 testing Feature requests related to testing

Comments

@dominik-fielmann
Copy link

dominik-fielmann commented Jan 17, 2020

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.

@dylanwulf
Copy link

dylanwulf commented Jan 17, 2020

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.

@insidewhy
Copy link

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.

@richardwu
Copy link

👍 on this

@insidewhy
Copy link

@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.

@david-morris
Copy link

@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.

@insidewhy
Copy link

insidewhy commented Dec 18, 2021

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?

@david-morris
Copy link

@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.

@riezebosch
Copy link

@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.

@RobinTail
Copy link

@jerelmiller
Copy link
Member

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!

@ARkrOSClou
Copy link

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

@jerelmiller
Copy link
Member

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 🙂

@jerelmiller jerelmiller removed the project-apollo-client (legacy) LEGACY TAG DO NOT USE label Jan 28, 2024
@ferrata
Copy link

ferrata commented May 17, 2024

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}>
// ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧪 testing Feature requests related to testing
Projects
None yet
Development

No branches or pull requests