How to fix TypeError is not a function (testing promises with Jest)
47,499
It looks like the reason why you're getting this error has to do with the data you're mocking through Jest.
Try using jest.fn()
to mock your getIdToken
as a function, rather than a string:
const mockGetIdToken = jest.fn(() => 'abc123');
jest.mock('services/firebase', () => new Promise(resolve => resolve({
signInWithEmailAndPassword: () => Promise.resolve({ getIdToken: mockGetIdToken }),
getIdToken: mockGetIdToken,
signOut: () => jest.fn()
})));
describe('login actions', () => {
let store;
beforeEach(() => {
store = mockStore({});
});
it('signIn should call firebase', () => {
const user = {
email: '[email protected]',
password: 'abd123'
};
return store.dispatch(signIn(user.email, user.password))
.then(() => {
console.log('TEST signIn SUCCESS');
expect(mockSignIn).toHaveBeenCalled();
expect(store.getActions()).toEqual({
type: USER_ON_LOGGED_IN
});
})
.catch((err) => {
console.log('TEST signIn ERROR =>', err);
});
});
Related videos on Youtube
Author by
Leon Gaban
Investor, Powerlifter, Crypto investor and global citizen You can also find me here: @leongaban | github | panga.ventures
Updated on May 20, 2020Comments
-
Leon Gaban about 4 years
I have a passing test now thanks to the answer here: How to test is chained promises in a jest test?
However I'm still getting an error in the catch part of my test.
I seem to not be able to correctly mock or spy this part in the actions file:
.then(res => res.getIdToken())
TEST signIn ERROR => TypeError: res.getIdToken is not a function
The Test
jest.mock('services/firebase', () => new Promise(resolve => resolve({ signInWithEmailAndPassword: () => Promise.resolve({ getIdToken: 'abc123' }), getIdToken: () => jest.fn(), signOut: () => jest.fn() }))); describe('login actions', () => { let store; beforeEach(() => { store = mockStore({}); }); it('signIn should call firebase', () => { const user = { email: '[email protected]', password: 'abd123' }; return store.dispatch(signIn(user.email, user.password)) .then(() => { console.log('TEST signIn SUCCESS'); expect(mockSignIn).toHaveBeenCalled(); expect(store.getActions()).toEqual({ type: USER_ON_LOGGED_IN }); }) .catch((err) => { console.log('TEST signIn ERROR =>', err); }); });
The SignIn actions/Login
// Sign in action export const signIn = (email, password, redirectUrl = ROUTEPATH_DEFAULT_PAGE) => (dispatch) => { dispatch({ type: USER_LOGIN_PENDING }); return firebase .then((auth) => { console.log('auth =>', auth); return auth.signInWithEmailAndPassword(email, password); }) .catch((e) => { console.error('actions/Login/signIn', e); // Register a new user if (e.code === LOGIN_USER_NOT_FOUND) { dispatch(push(ROUTEPATH_FORBIDDEN)); dispatch(toggleNotification(true, e.message, 'error')); } else { dispatch(displayError(true, e.message)); setTimeout(() => { dispatch(displayError(false, '')); }, 5000); throw e; } }) // I can't seem to mock this correctly .then(res => res.getIdToken()) .then((idToken) => { if (!idToken) { dispatch(displayError(true, 'Sorry, there was an issue with getting your token.')); } dispatch(onCheckAuth(email)); dispatch(push(redirectUrl)); }); };
-
Daniel Conde Marin over 6 yearsReplace
signInWithEmailAndPassword: () => Promise.resolve({ getIdToken: 'abc123' })
withsignInWithEmailAndPassword: () => Promise.resolve({ getIdToken: () => 'abc123' })
. It needs to be a function, my original answer was already like a function :) stackoverflow.com/questions/48468299/…
-