Last updated: Mar 7, 2024
Reading timeยท5 min
To check multiple arguments on multiple calls for Jest mocks:
mock.calls
property to get an array containing the arguments the
mock function was called with.expect()
function to assert that the actual values match the
expected values.function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { // ๐๏ธ pass mocked function to wrapper() wrapper(myMock, 50, 100); wrapper(myMock, 150, 200); // ๐๏ธ [ [ 50, 100 ], [ 150, 200 ] ] console.log(myMock.mock.calls); expect(myMock.mock.calls).toEqual([ [50, 100], // ๐๏ธ first call args [150, 200], // ๐๏ธ second call args ]); });
If I run the npx jest
command, I can see that the test passes.
Note: If you need to clear your mocks before each test, add the following
beforeEach()
hook.
beforeEach(() => { jest.clearAllMocks(); });
We created a mock function and passed the mock to the wrapper()
function.
The wrapper function calls the mock with the other two supplied values (a
and
b
).
The mock.calls
property returns an array of arrays that contain the arguments
that the mock function was called with.
The first array contains the arguments of the first mock call and the second array contains the values of the second mock call.
You can use the length
property on the mock.calls
array if you need to
assert that the mock function has been called N times.
function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { // ๐๏ธ pass mocked function to wrapper() wrapper(myMock, 50, 100); wrapper(myMock, 150, 200); console.log(myMock.mock.calls); expect(myMock.mock.calls).toEqual([ [50, 100], [150, 200], ]); expect(myMock.mock.calls.length).toBe(2); });
The mock.calls.length
property returns an integer representing the number of
times the mock function has been called.
If I run the npx jest
command, I can see that the test passes.
npx jest
There is also a toHaveBeenCalledTimes()
helper method that can be used to
check if your mock function was called N times.
expect(myMock).toHaveBeenCalledTimes(2);
The assertion above is equivalent to the following assertion.
expect(myMock.mock.calls.length).toBe(2);
toHaveBeenNthCalledWith
helper to check multiple arguments on multiple calls of a Jest mockYou can also use the toHaveBeenNthCalledWith helper method to check multiple arguments on multiple calls of a Jest mock function.
function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); expect(myMock).toHaveBeenNthCalledWith(1, 'A', 'B'); expect(myMock).toHaveBeenNthCalledWith(2, 'C', 'D'); expect(myMock.mock.calls.length).toBe(2); });
Note: If you need to clear your mocks before each test, add the following
beforeEach()
hook.
beforeEach(() => { jest.clearAllMocks(); });
This time we called the mock function 2 times:
A
and B
C
and D
The first argument the toHaveBeenNthCalledWith
method takes is the nthCall
integer, starting with 1.
The first call of the mock function has an nthCall
value of 1 and the second
has an nthCall
value of 2, etc.
The next arguments the toHaveBeenNthCalledWith()
method takes are the expected
arguments that the mock function was called with for the specific nthCall
.
Note that the toHaveBeenNthCalledWith
can also be referenced using its alias
nthCalledWith
.
function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); expect(myMock).nthCalledWith(1, 'A', 'B'); expect(myMock).nthCalledWith(2, 'C', 'D'); expect(myMock.mock.calls.length).toBe(2); });
The code sample above uses the nthCalledWith
alias to achieve the same result.
If you want to automate the process:
nthCalledWith
method to check if the expected arguments match the
actual arguments the mock function was called with.function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); const expectedArguments = [ ['A', 'B'], ['C', 'D'], ]; expectedArguments.forEach((args, index) => { expect(myMock).nthCalledWith(index + 1, ...args); }); expect(myMock.mock.calls.length).toBe(2); });
The expectedArguments
array stores the arguments the mock function was called
with, in the specified order.
On each iteration, we add 1 to the index of the current iteration and assert that the expected arguments match the actual arguments.
toHaveBeenCalledWith
helper to check multiple arguments on multiple calls of a Jest mockYou can also use the toHaveBeenCalledWith
utility method to check multiple
arguments on multiple calls of a Jest mock.
function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { // ๐๏ธ pass mocked function to wrapper() wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); wrapper(myMock, 'E', 'F'); expect(myMock).toHaveBeenCalledTimes(3); expect(myMock).toHaveBeenCalledWith('A', 'B'); expect(myMock).toHaveBeenCalledWith('C', 'D'); expect(myMock).toHaveBeenCalledWith('E', 'F'); });
The toHaveBeenCalledWith method is used to ensure that a mock function was called with specific arguments.
However, notice that we don't specify on which call the mock function was passed the specified arguments.
If you want to test that on the nth call the mock was passed specific arguments,
you have to use the nthCalledWith
method from the previous subheading.
The toHaveBeenCalledWith
method is also accessible with the toBeCalledWith
alias.
function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { // ๐๏ธ pass mocked function to wrapper() wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); wrapper(myMock, 'E', 'F'); expect(myMock).toHaveBeenCalledTimes(3); expect(myMock).toBeCalledWith('A', 'B'); expect(myMock).toBeCalledWith('C', 'D'); expect(myMock).toBeCalledWith('E', 'F'); });
The code sample above is equivalent to the previous one.
You can also manually check for the values of multiple arguments on multiple calls.
beforeEach(() => { jest.clearAllMocks(); }); function wrapper(fn, a, b) { fn(a, b); } // ๐๏ธ mock a function const myMock = jest.fn(); test('example test', () => { wrapper(myMock, 'A', 'B'); wrapper(myMock, 'C', 'D'); // ๐๏ธ [ [ 'A', 'B' ], [ 'C', 'D' ] ] console.log(myMock.mock.calls); expect(myMock.mock.calls[0][0]).toEqual('A'); expect(myMock.mock.calls[0][1]).toEqual('B'); expect(myMock.mock.calls[1][0]).toEqual('C'); expect(myMock.mock.calls[1][1]).toEqual('D'); expect(myMock).toHaveBeenCalledTimes(2); });
We manually access the values of each subarray in the mock.calls
array and
check if each argument is equal to the expected value.
The first set of square brackets is used to access the subarray at the given index.
The second set of square brackets is used to access a specific element in the given subarray.
You can learn more about the related topics by checking out the following tutorials:
process
function