How can I test async react redux call

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How can I test async react redux call



I'm trying to test login user actions, but I always get the empty array for my store.getActions(). How can I test login user function, to get action type SET_USER if it is success or ERROR if not. Here is my code for auth actions


store.getActions()


SET_USER


export const loginUser = (user) => dispatch =>
axios
.post('http://localhost:5000/users/login', user)
.then(res =>

dispatch(
type: 'SET_USER',
payload: res.data
)
)
.catch(err =>
dispatch(
type: 'ERROR',
payload: err.response
)
);
;



and here for auth actions test


import loginUser from '../../actions/authActions';

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

describe('Auth actions', () =>
const user =
email: 'user@test.com',
password: '123456',


let store;
beforeEach(() =>
store = mockStore();
);

it('should login user', () =>
store.dispatch(loginUser())
console.log(store.getActions())
);
);




1 Answer
1



It looks like dispatch needs to be passed first to create a function that accepts a user and responds using the dispatch:


// ---- authActions.js ----
import axios from 'axios';

export const loginUser = dispatch => user =>
axios
.post('http://localhost:5000/users/login', user)
.then(res =>

dispatch(
type: 'SET_USER',
payload: res.data
)
)
.catch(err =>
dispatch(
type: 'ERROR',
payload: err.response
)
);
;



To test it you need to mock axios.post() and create a mock to pass as dispatch. You will need to make the test functions async and pause them to let the callbacks execute. All together the test looks like this:


axios.post()


dispatch


async


// ---- authActions.test.js ----
import axios from 'axios';
import loginUser from '../../actions/authActions';

describe('Auth actions', () =>

const user =
email: 'user@test.com',
password: '123456',


let postMock;
let dispatchMock;

beforeEach(() =>
postMock = jest.spyOn(axios, 'post');
postMock.mockImplementation((url, u) =>
if (u === user)
return Promise.resolve( data: 'mocked response' );

else
return Promise.reject( response: 'login failed' );

);
dispatchMock = jest.fn();
);

afterEach(() =>
postMock.mockRestore();
);

it('should login user', async () =>
loginUser(dispatchMock)(user);
// Pause the synchronous test here to let the event loop cycle
await Promise.resolve();

expect(dispatchMock).toHaveBeenCalledTimes(1);
expect(dispatchMock).toHaveBeenCalledWith(
type: 'SET_USER',
payload: 'mocked response'
);
);

it('should return error', async () =>
loginUser(dispatchMock)( email: 'something', password: 'invalid' );
// Allow two event loop cycles for the catch to execute
await Promise.resolve().then();

expect(dispatchMock).toHaveBeenCalledTimes(1);
expect(dispatchMock).toHaveBeenCalledWith(
type: 'ERROR',
payload: 'login failed'
);
);
);





Thanks, but I alway get ERROR action type, with payload of undefined.
– Dalies
Aug 11 at 13:01





@Dalies I just realized you should probably be passing dispatch first so I've updated my answer with the recommended code change and a functioning test
– brian-lives-outdoors
Aug 11 at 15:29


dispatch





@Dalies friendly reminder to upvote and mark as accepted if an answer provides the info you need. If you have any further questions let us know
– brian-lives-outdoors
Aug 13 at 15:13






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard