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

Provide a way to specify a custom matcher in MockedProvider #245

Closed
prowe opened this issue Jul 23, 2020 · 7 comments
Closed

Provide a way to specify a custom matcher in MockedProvider #245

prowe opened this issue Jul 23, 2020 · 7 comments
Labels
project-apollo-client (legacy) LEGACY TAG DO NOT USE 🧪 testing Feature requests related to testing

Comments

@prowe
Copy link

prowe commented Jul 23, 2020

Support for dynamic matching of MockedResponses and dynamic return data

Problem

The MockedProvider has a mocks prop that allows users to specify the variables and query to match what mock response to return. However, this requires the developer know the exact variables that are being passed to the query. In a lot testing situations, the goal of the test is not to test specific variables but rather, return a mock response to test other behavior.

It is also difficult to assert that a particular query/mutation was executed and what variables it was executed with. The mock allows a developer to specify a Fetch function to return the response, but this method does not get any parameters that can be asserted to ensure it can return the correct response or generate a response (for example, responding with an object that has the id requested).

Proposed Solution

I propose two modifications to the API:

  • Extend the MockedResponse api with a field of type (variables: any) => boolean that if provided is used to match variables rather than strict equality on the structure. Clients can provide this function instead of variables on the request to dynamically determine if the variables are a match for a specific query/mutation.
  • Modify FetchFunction to take a parameter of the Variable type. This allows a fetch function to dynamically determine the data it returns. It also allows a mock to be specified for the fetch function so that assertions can be made on the specific variables passed to it.
@jeggy
Copy link

jeggy commented Feb 11, 2021

We are also facing the same difficulty here. As we have a component that generates some variables, but two objects with the same fields and nested fields are not equal to each other in javascript. This makes it impossible for me to mock the data, even if I know the exact variables. So I would like to just give it true always or use something like the lodash _.isEqual.

@aghArdeshir
Copy link

If I'm not mistaken, we have a use case that could benefit from this feature too. Sometimes not all the queries actually matter for a test case, and the count is too long.

In those cases a code like this:

const mocks = [
  {
    request: { query: getData1 },
    result: { data: { Data1: {} } },
  },
  {
    request: { query: getData2 },
    result: { data: { Data2: {} } },
  },
  {
    request: { query: getData3 },
    result: { data: { Data3: {} } },
  },
  {
    request: { query: getData4 },
    result: { data: { Data4: {} } },
  },
  {
    request: { query: getData5 },
    result: { data: { Data5: {} } },
  },
];

test("something", () => {
  <MockedProvider mocks={mocks}>
    <SomeComopnent />
  </MockedProvider>;
});

could be changed to this:

test("something", () => {
  <MockedProvider
    mocks={(query, variables) => {
      if (
        query === somethingImportantQuery &&
        variables.something === someOtherThing
      ) {
        return {
          data: {
            // ...
          },
        };
      } else {
        return {
          data: {},
        };
      }
    }}
  >
    <SomeComopnent />
  </MockedProvider>;
});

Or something even better

@promontis
Copy link

For people who have the same problem, you might want to use https://mswjs.io/. It is highly recommended from several pioneers, and supports this use case.

Instead of mocking via MockedProvider, you can mock on network level. Don't have to wait on this feature.

@aghArdeshir
Copy link

@promontis It is fine for restful APIs. For Apollo client users, we, need to care about equality and deep equality and variables and also caching etc.... Which MokcedProvider of Apollo Client does them all automatically for us

@promontis
Copy link

@aghArdeshir Maybe I'm missing something, but the mocking is on the network level. So basically all of the features of Apollo client can and are used. Instead of actually doing a network call over the wire, it is intercepted on the level of the browser (service worker) and a mock is returned. So, basically it uses the Apollo client all the way. Like this mocking library is agonistic for whatever graphql (or any other protocol) client is used, that's what makes it highly recommended from the pioneers.

@aghArdeshir
Copy link

But it makes it hard to check for equality and deep equality of variables. And also in cases where user is using cache-only, there will be no network level interception.

@jerelmiller
Copy link
Member

Hey all 👋

We have merged apollographql/apollo-client#6701 that provides the functionality outlined in this request and will be released in the next minor v3.9.0. This functionality is currently available in prerelease versions starting with v3.9.0-alpha.0.

As such, I'm going to close this as completed. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project-apollo-client (legacy) LEGACY TAG DO NOT USE 🧪 testing Feature requests related to testing
Projects
None yet
Development

No branches or pull requests

6 participants