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
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);
});
});
// 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));
});
};
Return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will fail.
The Jest library provides the jest. fn() function for creating a “mock” function. An optional implementation function may be passed to jest. fn() to define the mock function's behavior and return value. The mock function's behavior may be further specified using various methods provided to the mock function such as .
To enable async/await in your project, install @babel/preset-env and enable the feature in your babel. config. js file.
Jest is an open-source Javascript testing framework developed by Facebook. It was mainly built for React, Node, Babel, TypeScript, Angular, Vue, and JavaScript-based applications. It primarily focuses on simplicity and support for large web applications.
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);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With