2

I'm trying to test async service that is returning response object after few intertwined API calls (axios with interceptors). Right now I'm using jest-mock-axios lib but I'm open to any alternatives or pure Jest.

(I removed irrelevant parts of code, originally written in TS)

// services/persons.js
import personsAgent from '../agents/persons';
import places from './places';
[...]
const get = async ({ search = '', limit, offset }) => { 
  const places = await places.get({ search: '', limit: 1000, offset: 0 });  // api call to endpoint url '/places/'
  const params = {
    search: !!search.length ? search : null,
    limit,
    offset,
  };
[...]
  return personsAgent.getAll({ ...params }).then(resp => {
    const results = sort(resp.data.results, .....).map((person, i) => {
      const place = places?.data?.results.filter(.....);

      return {
        id: person.id,
        name: person.first_name,
        surname: person.last_name,
        place,
      };
    });

    return {
      data: { ...resp.data, results },
      status: resp.status,
    };
  });
};
[....]
export default {
  get,
};
// agents/persons.js
import requests from '../utils/axios'; 
export default {
  getAll: (params: object) => requests.get('/persons/', { params }),
}
// services/persons.test.js
import mockAxios from 'jest-mock-axios';
import persons from './persons';

afterEach(() => {
  mockAxios.reset();
});

it('returns Persons data from API', async () => {
    let catchFn = jest.fn(),
      thenFn = jest.fn();

    persons
      .get({ search: '', limit: 10, offset: 0 })
      .then(thenFn)
      .catch(catchFn);

    expect(mockAxios.get).toHaveBeenCalledWith('/persons/', {
      params: { search: null, limit: 10, offset: 0 },
    }); // FAIL - received: '/places/', { search: '', limit: 1000, offset: 0 }

    let responseObj = {
      data: {
        results: ['test'],
      },
    };

    mockAxios.mockResponse(responseObj);

    expect(thenFn).toHaveBeenCalledWith({
      data: {
        results: ['test'],
      },
      status: 200,
    });

    expect(catchFn).not.toHaveBeenCalled();
  });

I'm using jest-mock-axios and for my others, simpler services without additional, internal call everything is working fine, but this is problematic. How to ignore or mock const places = await places.get() to focus on personsAgent.getAll()? Issue right now is that I'm testing request for const places = await places.get() and there is no secondary request for personsAgent.getAll(). axios.getReqByUrl('/persons/') // null

Any ideas, examples or alternatives? Thx in advance!

Bartek Ł.
  • 21
  • 3
  • Did you try to only mock the result of the request? Like `req.getAll = jest.fn().mockReturnedValue({something})` – João Mazagão Aug 19 '20 at 12:44
  • Hi Joao, thanks for response! Can you elaborate how to use mock**Return**Value and how it be different in context for example I showcased? I tried right now to use it like, for example: `const myMockFn = jest.fn().mockReturnValue(resultObj);` `let persons.get({ search: '', limit: 10, offset: 0 }).then(myMockFn).catch(catchFn);` IMO this not changing main issue, that there are two axios async calls, there should be two mock requests but it looks like there is always only one – Bartek Ł. Aug 19 '20 at 20:19
  • So, the jest.fn() is a mock function, and you can mock the value directly of the function persons.get like this `persons.get = jest.fn().mockReturnValue({foo})` with this your person.get in that scope always returns bla. If you want to return one exception and you persons.get are a promise you can mock with the value `persons.get = jest.fn().mockRejectValue({bar})` and in that scop, the persons.get always returns the exception in that scope. – João Mazagão Aug 20 '20 at 11:59
  • If you are testing your fetch, you shouldn't test the abstraction of that, you need to test only your window and behavior. Because for me this test should be inside of your backend app, and for your test case, you only need to mock the object value and the rejection of the request. If you don't understand yet, please ping me here again, and I try to help you again. – João Mazagão Aug 20 '20 at 12:05

0 Answers0