Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot mock useMutation using MockProvider

I have been using MockProvider from Apollo Client successfully in mocking normal GQL queries, but when I try to mock mutations it does not seem to work.

If I try to mock a useMutation using the MockProvider I get an InvariantError.

The component I am trying to test is :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';

// Define the GraphQL mutation
const ADD_TASK = gql`
  mutation AddTask($title: String!) {
    addTask(title: $title) {
      id
      title
    }
  }
`;

export const AddTaskForm = () => {
  const [title, setTitle] = useState('');

  const [addTask, { data, loading, error }] = useMutation(ADD_TASK);

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      await addTask({ variables: { title } });
      setTitle(''); 
    } catch (err) {
      console.error('Error adding task', err);
    }
  };

  return (
    <div>
      <h2>Add New Task</h2>
      <form onSubmit={handleSubmit}>
        <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Enter task title" />
        <button type="submit" disabled={loading}>
          {loading ? 'Adding...' : 'Add Task'}
        </button>
      </form>
      {error && <p>Error occurred: {error.message}</p>}
      {data && <p>Task {data.addTask} added successfully!</p>}
    </div>
  );
};

export default AddTaskForm;

My test file looks like this :

// AddTaskForm.test.js
import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { MockedProvider } from '@apollo/client/testing'; // Mock provider from Apollo
import userEvent from '@testing-library/user-event';
import AddTaskForm, { ADD_TASK } from './AddTaskForm';

// Mock GraphQL mutation response
const mocks = [
  {
    request: {
      query: ADD_TASK,
      variables: { title: 'Test Task' },
    },
    result: {
      data: {
        addTask: {
          id: '1',
          title: 'Test Task',
        },
      },
    },
  },
];

test('should add a task successfully', async () => {
  // Render component with MockedProvider to mock Apollo's useMutation
  render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <AddTaskForm />
    </MockedProvider>
  );

  // Ensure the form and button are present
  const input = screen.getByPlaceholderText(/enter task title/i);
  const submitButton = screen.getByText(/add task/i);

  // Simulate typing into the input field
  userEvent.type(input, 'Test Task');

  // Simulate clicking the submit button
  fireEvent.click(submitButton);

  // Ensure the loading state is displayed
  expect(submitButton).toBeDisabled();
  expect(submitButton).toHaveTextContent('Adding...');

  // Wait for mutation to complete
  await waitFor(() => {
    expect(screen.getByText('Task "Test Task" added successfully!')).toBeInTheDocument();
  });

  // Check that input is cleared after task is added
  expect(input.value).toBe('');
});

However when I run the test I get an "Invariant" error that looks like this :

An error occurred! For more details, see the full error text at https://go.apollo.dev/c/err#%7B%22version%22%3A%223.11.1%22%2C%22message%22%3A76%2C%22args%22%3A%5B%5D%7D
Invariant Violation: An error occurred! For more details, see the full error text at https://go.apollo.dev/c/err#%7B%22version%22%3A%223.11.1%22%2C%22message%22%3A76%2C%22args%22%3A%5B%5D%7D
at new InvariantError (C:\dev\AKOM\frontend\node_modules\ts-invariant\lib\invariant.js:11:28)
at Object.originalInvariant [as invariant] (C:\dev\AKOM\frontend\node_modules\ts-invariant\lib\invariant.js:24:15)

Navigating to this URL gives me nothing useful.

I have carefully analyzed my component and test and I can’t see anything wrong with the code that I have.

>Solution :

You are not exporting ADD_TASK from your component file, so you pass a nonexistent variable (=undefined) into the mock.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading