Reputation: 3112
I am trying to use jest
to test calls to firebase
. Firebase is an online database service offered by Google. I am mocking the firebase
module like below
'use strict';
const firebase = jest.genMockFromModule('firebase');
const ref = jest.fn(() => {
return {
child: jest.fn(() => {
return ref
}),
update: jest.fn(() => {
console.log('Called update')
return Promise.resolve()
})
}
})
firebase.initializeApp = jest.fn()
firebase.database = jest.fn(() => {
return {
ref: ref
}
})
module.exports = firebase
I am only mocking the functions that I need to test at the moment. Below is my test case.
it('+++ actionCreator addAlarm', () => {
const store = mockStore(initialState)
store.dispatch(ActionCreators.addAlarm(alarm));
// Make sure that the scheduleNotifications API is called
expect(scheduleNotifications).toHaveBeenCalled();
expect(firebase.initializeApp).toHaveBeenCalled();
expect(firebase.database().ref().update).toHaveBeenCalled();
});
The last line in the test case is trying to make sure that I am calling the firebase
update
function which is mocked.
Below is the console output
abcs-MBP-2:GalarmApp abc$ npm test
> [email protected] test /Users/abc/Projects/GalarmApp
> jest
FAIL __tests__/actionsSpecs.js
● >>>A C T I O N --- Test galarm actions: › +++ actionCreator addAlarm
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
at Object.<anonymous> (__tests__/actionsSpecs.js:58:52)
at tryCallTwo (node_modules/promise/lib/core.js:45:5)
at doResolve (node_modules/promise/lib/core.js:200:13)
at new Promise (node_modules/promise/lib/core.js:66:3)
at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
at tryCallOne (node_modules/promise/lib/core.js:37:12)
at node_modules/promise/lib/core.js:123:15
>>>A C T I O N --- Test galarm actions:
✕ +++ actionCreator addAlarm (8ms)
✓ +++ actionCreator setConnectionStatus (4ms)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 1 passed, 1 total
Time: 1.989s, estimated 2s
Ran all test suites.
console.warn node_modules/rn-host-detect/index.js:45
[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()
console.log __mocks__/firebase.js:11
Called update
The test case is failing on the line where I check that the update
function is called. If you look down in the console output, you will see that Called update
console is present which means that the update function is called but it is called after the test case has failed.
This is the addAlarm
action which is a thunk action
const addAlarm = (alarm) => (dispatch, getState) => {
if(alarm.status) {
NotificationManager.scheduleNotifications(alarm);
}
const alarmObjForFirebase = this.createAlarmObjForFirebase(alarm)
firebaseRef.update(alarmObjForFirebase)
}
The call to firebase
update
function is not happening asynchronously as far as I understand.
Please let me know if you have pointers on how I may be able to fix this problem.
Upvotes: 2
Views: 461
Reputation: 3112
I have found the problem in my code and posting as a solution for others benefit. The problem is the way the update
mock was defined. The way it was defined, I was getting a new instance of the update
mock function every time I will make a call to firebase.database().ref().update. Since this is a new instance of the mock function, it wouldn't contain any data about
update` function being called in the past.
I needed to change the code as follows
const update = jest.fn(() => {
return Promise.resolve()
})
const ref = jest.fn(() => {
return {
update: update
}
})
This way, I am not creating new instances of the update
mock function and I was able to assert that it has been called during the testcase.
Upvotes: 3