Check multiple arguments on multiple calls for Jest Mocks

avatar
Borislav Hadzhiev

Last updated: Mar 7, 2024
5 min

banner

# Table of Contents

  1. Check multiple arguments on multiple calls for Jest mocks
  2. Using the toHaveBeenNthCalledWith helper to check multiple arguments on multiple calls of a Jest mock
  3. Using the toHaveBeenCalledWith helper to check multiple arguments on multiple calls of a Jest mock
  4. Manually checking multiple arguments on multiple calls for jest mocks

# Check multiple arguments on multiple calls for Jest mocks

To check multiple arguments on multiple calls for Jest mocks:

  1. Use the mock.calls property to get an array containing the arguments the mock function was called with.
  2. The property will return an array of arrays where each array contains the values the mock was called with.
  3. Use the expect() function to assert that the actual values match the expected values.
example.test.js
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.

test passes with supplied argument arrays

Note: If you need to clear your mocks before each test, add the following beforeEach() hook.

example.test.js
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.

example.test.js
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.

shell
npx jest

test passes mock function called two times

There is also a toHaveBeenCalledTimes() helper method that can be used to check if your mock function was called N times.

example.test.js
expect(myMock).toHaveBeenCalledTimes(2);

The assertion above is equivalent to the following assertion.

example.test.js
expect(myMock.mock.calls.length).toBe(2);

# Using the toHaveBeenNthCalledWith helper to check multiple arguments on multiple calls of a Jest mock

You can also use the toHaveBeenNthCalledWith helper method to check multiple arguments on multiple calls of a Jest mock function.

example.test.js
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.

example.test.js
beforeEach(() => { jest.clearAllMocks(); });

This time we called the mock function 2 times:

  • the first time with the strings A and B
  • the second time with the strings 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.

example.test.js
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:

  1. Store the expected arguments the mock function was called with, in an array.
  2. Iterate over the array using Array.forEach.
  3. Use the nthCalledWith method to check if the expected arguments match the actual arguments the mock function was called with.
index.test.js
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.

# Using the toHaveBeenCalledWith helper to check multiple arguments on multiple calls of a Jest mock

You can also use the toHaveBeenCalledWith utility method to check multiple arguments on multiple calls of a Jest mock.

index.test.js
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'); });

test with to have been called with passes

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.

index.test.js
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.

# Manually checking multiple arguments on multiple calls for jest mocks

You can also manually check for the values of multiple arguments on multiple calls.

index.test.js
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.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev