Ramesh Lamani
Ramesh Lamani

Reputation: 1127

How to write JEST test cases for the callback API

I have created a API service factory, passing dynamically URL, function as a parameter. Once it success data comes in the callback function and its working fine as per expected. For same I am going to write JEST test cases. I couldn't fine the right approach to do it. Can help someone. Great appreciate.

Code is here

function userLogin(username, password) {
  const reqBody = {
    companyEmailAddress: username,
    password,
  };
  const url = `${config.apiBaseUrl}${serviceMethodConstants.login}`;
  return (dispatch) => {
    dispatch(serviceFactory.postData(url, false, reqBody, function (response, dispatch) {
      if (response !== undefined) {
        console.log(response )
      }
    }));
  };
}

For same I wrote JEST test case, but it is not showing any error or success message as expected.

JEST test code

import { userConstants } from './constants';
import { serviceFactory } from '../../services/_helpers/serviceFactory';

const loginData = {
  companyEmailAddress: '[email protected]',
  password: 'Ramesh@1',
};

axiosMock.onPost(routeUrl).reply(200, JSON.stringify(loginData));
const spy = jest.spyOn(axios, 'post');
await store.dispatch(userActions.userLogin(...loginData, function (response, dispatch) {
    expect(response.message).toEqual('Failure');
    expect(spy).toBeCalled();
}));

enter image description here enter image description here

Upvotes: 0

Views: 1132

Answers (1)

Estus Flask
Estus Flask

Reputation: 222980

userLogin action creator (a thunk) doesn't accept a callback and doesn't do a request. It's unknown whether store.dispatch returns a promise that could be awaited.

A proper strategy for unit testing is to mock everything but tested unit. Since serviceFactory abstraction is in use, Axios shouldn't be involved. Action creator can be tested without Redux involved, either.

const dispatch = jest.fn();
const postDataResult = {};
jest.spyOn(serviceFactory, 'postData').mockReturnValue(postDataResult);

userActions.userLogin('user', 'pass')(dispatch);

expect(serviceFactory.postData).toBeCalledWith(url, false, {...}, expect.any(Function));
expect(dispatch).toBeCalledWith(postDataResult);

The test can stay synchronous this way.

Upvotes: 1

Related Questions