I have a particular function that needs to be unit tested. This function calls another one which is in the same file. Their implementation looks something like this:
const action1 = () => dispatch => {
// do something
}
const action2 = () => dispatch => {
// do something else
console.log('before')
dispatch(action1())
console.log('after')
}
The main one that is giving me trouble is action2 which I cannot figure out how to test whether or not action1 has been called. Here are the different iterations of my test.
Version 1 - using jest.spyOn
One of my attempts is making a jest spy on action1. This is not working, gives me the good ol'
Expected number of calls: >= 1 Received number of calls: 0
import * as MyActions from '../myActions'
import { action1, action2 } from '../myActions'
describe('myActions', () => {
describe('action1', () => {
test('should properly run action1', () => {
// everything is tested and works as expected
})
})
describe('action2', () => {
test('should properly run action2', () => {
const action1Spy = jest.spyOn(MyActions, 'action1')
expect(action1Spy).toHaveBeenCalled() // error here
})
})
})
Version 2 - using jest.mock in the action2 describe block
I then try to mock action1 with jest.mock, but since I do actual unit tests for action1, I tried to put it in its describe block. Not sure if this is allowed, but it doesn't matter because it did not work anyway. Got he following error:
Matcher error: received value must be a mock or spy function
The code like this:
import { action1, action2 } from '../myActions'
describe('myActions', () => {
describe('action1', () => {
test('should properly run action1', () => {
// everything is tested and works as expected
})
})
describe('action2', () => {
jest.mock('../myActions', () => ({
...jest.requireActual('../myActions'),
action1: jest.fn(),
}))
test('should properly run action2', () => {
const action1Spy = jest.spyOn(MyActions, 'action1')
expect(action1Spy).toHaveBeenCalled() // error here
})
})
})
Version 3 - using jest.mock on the file root describe block
As I grow more desperate, I removed the action1 unit tests, and tried to do the above on the file root. But again, I get the error of it never being called. Also... This method may cause problems for action1's unit tests so, even if it did work I am not sure how to get around it.
Expected number of calls: >= 1 Received number of calls: 0
import { action1, action2 } from '../myActions'
jest.mock('../myActions', () => ({
...jest.requireActual('../myActions'),
action1: jest.fn(),
}))
describe('myActions', () => {
describe('action1', () => {
test('should properly run action1', () => {
// skipped for now
})
})
describe.only('action2', () => {
test.only('should properly run action2', () => {
const action1Spy = jest.spyOn(MyActions, 'action1')
expect(action1Spy).toHaveBeenCalled() // error here
})
})
})
Anyway, this is where we are at.
I have surrounded my action1 calls with console.logs as you can see above. And indeed they are being logged, so it is supposed to be called.
I do also realize that the call is within a dispatch, but this works just fine in other cases and don't know how else to get around this.