Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest - check that item does not contain object with some property

This is my response I need to check:

[
  { _id: 'dislike', count: 1 },
  { _id: 'hate', count: 1 },
  { _id: 'trivial', count: 1 }
]

Checking the existing values is easy:

expect(response.data).toContainEqual({ _id: 'trivial', count: 1 });
expect(response.data).toContainEqual({ _id: 'dislike', count: 1 });
expect(response.data).toContainEqual({ _id: 'hate', count: 1 });

But I need to check that the array does not contain object with { _id: 'neutral' }. Following test looked successful because the test passed:

expect(response.data).not.toContain({ _id: 'neutral', count: 0 });

But I wanted to ensure that it does what I expect so I added a test that shall fail. But it does not:

expect(response.data).not.toContain({ _id: 'hate', count: 1 });

Can you see? Both tests toContainEqual and not.toContain are valid. How can I ensure that the array does not hold object with a property _id: 'neutral'?

like image 332
Leos Literak Avatar asked Dec 22 '22 18:12

Leos Literak


2 Answers

The matcher toContain checks if an item is in the array by using the strict equality check. That means that if you don't pass the reference to the object you are trying to test, it will always return false.

Thus, if you check:

expect(response.data).toContain({ _id: 'trivial', count: 1 });

It will fail, because, even though your response.data contains an object with those same attributes and values, it's not the same object (it does not point to the same reference).

That's the reason why:

expect(response.data).not.toContain({ _id: 'neutral', count: 0 });

Will always return true.

If you want to check for a specific structure and values, you should use the toContainEqual matcher:

expect(response.data).not.toContainEqual({ _id: 'hate', count: 1 });

Also, if you want to check the whole structure and values of your response data, you can simply use the toEqual matcher:

expect(response.data).toEqual([
    { _id: 'dislike', count: 1 },
    { _id: 'hate', count: 1 },
    { _id: 'trivial', count: 1 }
]);

This will check that response.data has exactly the structure and values you pass as a parameter. For extension, it is checking that it does not contain any other values.

like image 110
mgarcia Avatar answered Jan 05 '23 01:01

mgarcia


You could do it with Array.prototype.some()

expect(response.data.some(({_id}) => _id === "neutral")).toBe(false)

Array.prototype.some() returns a boolean true when the condition is first met, and false if not.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

like image 32
Tom Brown Avatar answered Jan 05 '23 01:01

Tom Brown