reactjsjestjsaxiosmoxios

How can I do a jest test in this function in React axios?


I guys I created a service in React and I need to test this part of the service, I'm using axios and Jest to do this. I have the next code in React :

import axios from 'axios';
import Endpoints from './endpoints';
const baseUrl = Endpoints.getBackendEndpoint();

export const validateName =  (nameObject, callback) => {
 axios.post(`${baseUrl}/validateName`, {...nameObject})
   .then(response =>{ 
      response.data
    })
   .then(data => callback(data));
};

I don't need return the promise because all the work is doing by the callback() function.

This is the code that I have in Jest:

mport moxios from 'moxios';
import * as service from '../service';
import mockResponses from './service.test.json';
import Endpoints from '../endpoints';


const validateObjName = {
    Id: 1,
    Name: 'Bob',
  }

beforeEach(() => {
const baseUrl = Endpoints.getBackendEndpoint();
  moxios.stubRequest(
    `${baseUrl}/validateName`,
    { ...validateObjName },
    {
      status: 200,
      response: mockResponses.validateForm,
    }
  );
});

afterEach(() => {
  moxios.uninstall();
});

it('validateName()', () => {
   service.validateName(validateObjName, jest.fn());
});

It works, but still need to increase the Branch coverage.

Thanks for you help guys :D


Solution

  • To get code coverage the code has to run while a test is running so you will want to return the Promise so you can await it in your test so the then callbacks run during your test.

    Also, you can simplify validateName to this:

    import axios from 'axios';
    import Endpoints from './endpoints';
    const baseUrl = Endpoints.getBackendEndpoint();
    
    export const validateName = (nameObject, callback) => {
      return axios.post(`${baseUrl}/validateName`, { ...nameObject })
        .then(response => callback(response.data));
    };
    

    In your test you need to install moxios in your beforeEach and pass the mock response as the second parameter to moxios.stubRequest.

    Then use an async test function and await the Promise returned by validateName:

    import moxios from 'moxios';
    import * as service from '../service';
    import mockResponses from './service.test.json';
    import Endpoints from '../endpoints';
    
    const validateObjName = {
      Id: 1,
      Name: 'Bob',
    }
    
    beforeEach(() => {
      moxios.install();  // install moxios
      const baseUrl = Endpoints.getBackendEndpoint();
      moxios.stubRequest(
        `${baseUrl}/validateName`,
        {
          status: 200,
          response: mockResponses.validateForm
        }
      );  // response is the second argument
    });
    
    afterEach(() => {
      moxios.uninstall();
    });
    
    it('validateName()', () => {
      service.validateName(validateObjName, jest.fn());
    });
    
    it('validateName()', async () => {  // use an async test function
      const spy = jest.fn();
      await service.validateName(validateObjName, spy);  // await the Promise
      expect(spy).toHaveBeenCalledWith(mockResponses.validateForm);  // Success!
    });
    

    That should give you a working test and 100% code coverage.