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 tell if a mock was called on MockedProvider #84

Closed
noaelad opened this issue Jan 16, 2019 · 4 comments · Fixed by apollographql/react-apollo#2788
Closed

Ability to tell if a mock was called on MockedProvider #84

noaelad opened this issue Jan 16, 2019 · 4 comments · Fixed by apollographql/react-apollo#2788
Assignees

Comments

@noaelad
Copy link

noaelad commented Jan 16, 2019

When trying to write tests for a react component that contains a mutation, I'd like to verify that the mutation is actually called (and with the right variables). Currently the documentation on this topic suggests mocking the mutation result and testing that the component produces some sort of inspectable change as a result of the mutation.

https://www.apollographql.com/docs/react/recipes/testing.html#Testing-mutation-components

However this poses two problems:

  1. In the event that the component does not actually change after a mutation (such as a button that triggers a mutation and then provides no feedback to the user), it is impossible to test that the component actually triggered the mutation.
  2. Even if the component does change after the mutation (e.g. the text on the component changes from "click me" to "I have called your mutation"), testing this change does not verify that the component behaves as expected. For example, if a developer accidentally changes the component's implementation, such that clicking the button doesn't call the mutation, but does trigger a text change, the test would still pass.

One possible solution would be to allow more flexibility in how mocked responses are specified. If for example it were possible to pass in a method to the mock instead of a static result, then this could be utilized for this purpose, and perhaps other purposes as well:

let mutationWasCalled = false;
const mocks = [
  {
    request: {
      query: expectedMutation, 
      variables: expectedVariables,
    },
    result: () => {
      mutationWasCalled = true;
      return dataToReturnFromMutation;
    }
  }
]
const component = (
  <MockedProvider mocks={mocks}>
    <ComponentBeingTested>
  </MockedProvider>
)
// simulate click on the component
expect(mutationWasCalled).to.eq(true);

Another option that provides a bit less flexibility but would still solve this issue is to have some way to allow querying whether or not a specific mocked request was called, and\or how many times it was called.

Thanks for reading! Looking forward to your response.

@jwillesen
Copy link

I've run into this same situation where a component updates optimistically. The UI will change whether or not the mutation was actually called.

@hwillson hwillson self-assigned this Feb 7, 2019
hwillson added a commit to apollographql/react-apollo that referenced this issue Feb 8, 2019
The `result` property of a `MockedResponse` is currently
restricted to being a pre-configured fixed value. Allowing
results to be calculated/returned from a function instead of
being pre-configured, opens up new test verification paths,
that can be useful when using `MockedProvider`.

This commit adjusts `MockedResponse`’s `result` such that if
a function is set for its value, that function will be fired and
its result will be passed to the Observable matching the
incoming mocked `request`.

Fixes apollographql/apollo-feature-requests#84.
hwillson added a commit to apollographql/react-apollo that referenced this issue Feb 8, 2019
The `result` property of a `MockedResponse` is currently
restricted to being a pre-configured fixed value. Allowing
results to be calculated/returned from a function instead of
being pre-configured, opens up new test verification paths,
that can be useful when using `MockedProvider`.

This commit adjusts `MockedResponse`’s `result` such that if
a function is set for its value, that function will be fired and
its result will be passed to the Observable matching the
incoming mocked `request`.

Fixes apollographql/apollo-feature-requests#84.
@hwillson hwillson reopened this Feb 8, 2019
@hwillson
Copy link
Member

hwillson commented Feb 8, 2019

Thanks for the suggestion @noaelad - great idea! This change has been implemented and merged, and will be coming in the next react-apollo release. I'm going to keep this issue open to make sure we remember to update the docs to show that this is now possible. Thanks again!

@noaelad
Copy link
Author

noaelad commented Feb 12, 2019

Nice @hwillson thanks for implementing this! Looking forward to the next release to start using it =]

@ahayes91
Copy link

ahayes91 commented Nov 2, 2021

Is this documented anywhere folks? https://jkettmann.com/testing-apollo-how-to-test-if-a-mutation-was-called-with-mockedprovider indicates using newData but looking at the PR and doing a local test myself using a jest.fn() on result directly seems to work too.

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

Successfully merging a pull request may close this issue.

4 participants