Search code examples
javascriptreactjsaxiosjestjsreact-testing-library

Why am I unable to use mockResolvedValue here?


I’m unclear on how to mock my api response when using the following setup.

I have the following test:

import React from 'react';
import { cleanup, render, wait } from '@testing-library/react';
import axios from 'axios';
import Condition from './index.jsx';

jest.mock('axios', () => {
  return {
    create: jest.fn(() => ({
      get: jest.fn().mockResolvedValue({ data: {} }),
      interceptors: {
        request: { use: jest.fn(), eject: jest.fn() },
        response: { use: jest.fn(), eject: jest.fn() },
      },
    })),
  };
});


afterEach(cleanup);

test('fetches and displays data', async () => {
  axios.get.mockResolvedValue({ data: 'mock data' });
  const { container } = render(<Condition {...props} />);
  await wait(() => expect(container.textContent).toContain('Current milestone'));
  expect(container).toBeDefined();
});

… and the following api helper:

import axios from 'axios';

const api = axios.create({
  baseURL: window.apiPath,
  withCredentials: true,
});

api.interceptors.request.use(config => {
  const newConfig = Object.assign({}, config);
  newConfig.headers.Accept = 'application/json';

  return newConfig;
}, error => Promise.reject(error));

export default api;

My Condition component uses the following function to fetch data when it mounts:

const fetchAsync = async endpoint => {
  const result = await api.get(endpoint);
  setSuffixOptions(result.data.data);
  console.log('result.data.data', result.data.data);
};

The axios.get.mockResolvedValue({ data: 'mock data' }); line in the test causes the following error:

    TypeError: Cannot read property 'mockResolvedValue' of undefined

      124 |
      125 | test('fetches and displays data', async () => {
    > 126 |   axios.get.mockResolvedValue({ data: 'mock data' });
          |             ^
      127 |   const { container } = render(<Condition {...props} />);
      128 |   await wait(() => expect(container.textContent).toContain('Current milestone'));
      129 |   expect(container).toBeDefined();

Should I be using a different method for mocking the response?

EDIT Calling axios.create.get.mockResolvedValue({ data: 'mock data' }); results in the same error.


Solution

  • To mock your api response, you can use jest.spyOn in combination with mockImplementation, e.g. as follows:

    import api from './api';
    
    const mock = jest.spyOn(api,"get");
    mock.mockImplementation(() => Promise.resolve({ data: {} }));
    

    In the example above, the api.get method is replaced to emulate a successful call returning { data: 'mock data' }.

    It can be placed in your test function as follows:

    test('fetches and displays data', async () => {
        const mock = jest.spyOn(api, "get");
        mock.mockImplementation(() => Promise.resolve({ data: {} }));
        const { container } = render(<Condition {...props} />);
        await wait(() => expect(container.textContent).toContain('Current milestone'));
        expect(container).toBeDefined();
    });