Loose match one value in jest.toHaveBeenCalledWith
To re-iterate the comment by cl0udw4lk3r as I found this the most useful in my scenario:
If you have a method that accepts multiple parameters (not an object) and you only want to match some of these parameters then you can use the expect
object.
Example
method I want to test:
client.setex(key, ttl, JSON.stringify(obj));
I want to ensure the correct values are passed into the key
and ttl
but I'm not concerned what the object passed in is. So I set up a spy:
const setexSpy = jest.spyOn(mockClient, "setex");
and I can then expect this scenario thus:
expect(setexSpy).toHaveBeenCalledWith('test', 99, expect.anything());
You can also use more strongly typed calls using expect.any
(expect.any(Number)
) etc.
You can access the expected object for a better assertion using track.mock.calls[0][0]
(the first [0]
is the invocation number, and the second [0]
is the argument number). Then you could use toMatchObject
to find partially match the object, avoiding the dynamic parameters such as intervalInMilliseconds
.
This can be done with asymmetric matchers (introduced in Jest 18)
expect(track).toHaveBeenCalledWith(
expect.objectContaining({
"action": "PublicationPage",
"category": "PublicationPage",
"label": "7",
"name": "n/a"
})
)
If you use jest-extended
you can do something like
expect(track).toHaveBeenCalledWith(
expect.objectContaining({
"action": "PublicationPage",
"category": "PublicationPage",
"label": "7",
"name": "n/a",
"intervalInMilliseconds": expect.toBeWithin(999, 1002)
})
)