Kinda newbie to jest here.I am trying to write unit test cases for one of the async action creators in my React project using jest. I keep running into the error TypeError: Cannot read property 'then' of undefined
Below is my action creator:
import {loginService} from "./services";
export function login(email: string, password: string): (dispatch: ThunkDispatch<{}, {}, any>) => void {
return dispatch => {
dispatch(loggingIn(true));
loginService(email, password).then(
(response: any) => {
dispatch(loggingIn(false));
dispatch(loginAction(response));
},
error => {
//Code
}
dispatch(loggingIn(false));
dispatch(loginError(true, message));
}
);
};
}
./services.js
export const loginService = (username: string, password: string) => {
const requestOptions = {
method: "POST",
headers: {
//Headers
},
body: JSON.stringify({email: username, password: password})
};
return fetch(`url`, requestOptions)
.then(handleResponse, handleError)
.then((user: any) => {
//code
return user;
});
};
Given below is my test:
it("login", () => {
fetchMock
.postOnce("/users/auth", {
body: JSON.parse('{"email": "user", "password": "password"}'),
headers: {"content-type": "application/json"}
})
.catch(() => {});
const loginPayload = {email: "user", password: "password"};
const expectedSuccessActions = [
{type: types.LOGGING_IN, payload: true},
{type: types.LOGIN, loginPayload}
];
const expectedFailureActions = [
{type: types.LOGGING_IN, payload: true},
{type: types.LOGIN_ERROR, payload: {val: true, errorMessage: "error"}}
];
const store = mockStore({user: {}});
const loginService = jest.fn();
return store.dispatch(LoginActions.login("email", "password")).then(() => {
expect(store.getActions()).toEqual(expectedSuccessActions);
});
});
Please help
The end result returned by dispatching your
LoginActions.login()
action isvoid
(orundefined
). Not aPromise
, so not something you can call.then()
on in your test.Judging by your test code, you're using
fetch-mock
for yourfetchMock
. You should be able to wait for that to finish before testing that the store dispatched the correct actions:Note that the comments in your code seem to indicate that your
loginService
does some more things before returning from the.then()
callback. If that takes too long, waiting for thefetchMock
to finish might not be waiting long enough. In that case, you should consider returning thePromise
from yourLoginActions.login()
action so that you can test it. Whether or not you should depends on how much effort it would be to adjust your application to handle that, since you don't want your app to crash with any unhandled promise rejection errors in case the login fails.