Problem

Consider the following function and passing test

function foo(bar, arg) {
bar(Math.random(), arg);
}

test("bar is called", () => {
const barSpy = jest.fn();
foo(barSpy, "fake-argument");

expect(barSpy).toHaveBeenCalled();
});

foo is a function that calls bar with a random first argument and arg which is just passed through.

The test passes as expected, but what if we wanted to check that the second argument is equal to arg.

expect(...).toHaveBeenCalledWith(...args) requires the test to provide the exact list of arguments passed to our jest.fn spy during the call.


### Solution

Use the asymetric matcher expect.anything() to ignore the first argument passed to foo.

test("Match any argument", () => {
const barSpy = jest.fn();
foo(barSpy, "fake-argument");

expect(barSpy).toHaveBeenCalledWith(expect.anything(), "fake-argument");
});

### Better Solution

Use expect.any(constructor) to check that the first argument is a number

test("Match any number", () => {
const barSpy = jest.fn();
foo(barSpy, "fake-argument");

expect(barSpy).toHaveBeenCalledWith(expect.any(Number), "fake-argument");
});

### Other asymetric matchers

Jest also provides the following useful asymetric matchers:

expect.objectContaining(object) to check only certain properties of an object

expect.arrayContaining(array) to check only certain elements of an array

expect.stringContaining(string) to check part of a string


### Going further with jest-extended

If you need to be even more specific in your assertions, it might be worth checking out jest-extended

You will find useful additions to the base jest assertion API like:

myNumber.toBeWithin(0, 10)

myObject.toContainKeys([keys])

myText.toStartWith(prefix)

and many more ..


Happy testing :)