How to mock out async actions

Viewed 92

I'm trying to test this function:

function login(username, password) { 
    let user = { userName: username, password: password };
    return dispatch => {
        localStorageService.login(username, password).then((response) => {
            dispatch(resetError());
            dispatch(success( { type: userConstants.LOGIN, user} )); 
        }, (err) => {
            dispatch(error(err));
        }); 
    };

    function success(user) { return { type: userConstants.LOGIN, payload: user } };
};

Here is my test

const mockStore = configureStore([thunk]);
const initialState = {
    userReducer: {
        loggedInUser: "",
        users: [],
        error: ""
    }  
};
const store = mockStore(initialState);
jest.mock('./../../services/localStorageService');

describe("Login action should call localstorage login", () => {
    let localStorage_spy = jest.spyOn(localStorageService, 'login');
    store.dispatch(userActions.login(test_data.username, test_data.password)()).then( () => {
     expect(localStorage_spy).toHaveBeenCalled();  
    });
});

The error I get:

Actions must be plain objects. Use custom middleware for async actions.

A lot of resources online keep telling me to use thunk in my test for these actions but it's not working. The last thing it calls is dispatch(resetError()); and it breaks. I've never really found a resource online which is similar enough to my problem. My function returns a dispatch which returns a promise which returns another dispatch when the promise resolves. I'm just trying to get the function to return. I've put a spy on localStorageService.login and also mocked it out and I have an expect to make sure it was called. But of course the function is not returning

0 Answers
Related