apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.31k stars 2.65k forks source link

Testing which variables are sent in my mutation #9570

Open Spoutnik97 opened 2 years ago

Spoutnik97 commented 2 years ago

Hi,

I would like to test what variables are sent with my mutation. I have a reset password screen in React Native.

I saw [this article] (https://jkettmann.com/testing-apollo-how-to-test-if-a-mutation-was-called-with-mockedprovider) talking about newData key in mocks, but unfortunatelly, this function called with undefined...

Could you help me to understand what happens please?

My test:

it('reset the password when pressing on Reset Password button', async () => {
    const mocks = [
      {
        request: {
          query: RESET_PASSWORD_MUTATION,
          variables: {
            email: 'test@bam.tech',
          },
        },
        result: { data: { requestPassword: '' } },
        newData: jest.fn(() => {
          return { data: { requestPassword: '' } };
        }),
      },
    ];
    const forgotPasswordScreen  = render(  <MockedApolloProvider mocks={mocks} addTypename={false}>
<ForgotPasswordScreen />
</MockedApolloProvider>);

    const emailInput = forgotPasswordScreen.getByA11yLabel("Saisie de l'e-mail");
    const submitButton = forgotPasswordScreen.getByText('Réinitialiser mon mot de passe');

    await act(async () => {
      await fireEvent.changeText(emailInput, 'test@test.com');
      await fireEvent.press(submitButton);
    });

    expect(mocks[0].newData).toHaveBeenCalledWith({ variables: {email: "test@test.com" });

});

The test result displays:

  ● ForgotPasswordScreen › reset the password when pressing on Reset Password button

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: {"variables": {"email": "test@test.com"}}
    Received: called with 0 arguments

    Number of calls: 1

      75 |     });
      76 |
    > 77 |     expect(mocks[0].newData).toHaveBeenCalledWith({ variables: { email: 'test@test.com' } });
winjay-yu-awx commented 2 years ago

I have this question too

RichMatthews commented 1 year ago

I also have this question and I get Mocked response should contain either result or error when trying to use newData. even though newData exists on the type

masives commented 1 year ago

The same happens for query - both result and newData can be checked if they're called but we cannot make assertion about variables.

@RichMatthews - you cannot use newData alone, you have to either pass result or error. newData is used for requests after initial one

adarshem commented 1 year ago

I think the validation of what is being sent as a mutation variable is already done when you mock your request right?

If your mocked variable object is different from what the test is sending, then the test would fail. You do not need an explicit toHaveBeenCalledWith instead just toHaveBeenCalled is enough.

@Spoutnik97 If you want your test to work fine, kindly update this to pass correct emailId await fireEvent.changeText(emailInput, 'test@test.com'); because your mock is expecting email: 'test@bam.tech' and then assert expect(mocks[0].newData).toHaveBeenCalled();