How do I compare two collections in Jest ignoring element order?
Asked Answered
A

5

15

When writing a unit test in Jest, how can I test that an array contains exactly the expected values in any order?

In Chai, I can write:

const value = [1, 2, 3];
expect(value).to.have.members([2, 1, 3]);

What's the equivalent syntax in Jest?

Araxes answered 3/5, 2018 at 9:55 Comment(2)
Possible duplicate of Is there an Array equality match function that ignores element position in jest.js?Lesbian
Does this answer your question? Is there an Array equality match function that ignores element position in jest.js?Mint
S
12

Another way is to use the custom matcher .toIncludeSameMembers() from jest-community/jest-extended.

Example given from the README

test('passes when arrays match in a different order', () => {
    expect([1, 2, 3]).toIncludeSameMembers([3, 1, 2]);
    expect([{ foo: 'bar' }, { baz: 'qux' }]).toIncludeSameMembers([{ baz: 'qux' }, { foo: 'bar' }]);
});

It might not make sense to import a library just for one matcher but they have a lot of other useful matchers I've find useful.

Additional note, if you're using Typescript, you should import the types for the methods added to expect with this line:

import 'jest-extended';
Seat answered 16/1, 2020 at 0:45 Comment(0)
B
4

I would probably just check that the arrays were equal when sorted:

expect(value.sort()).toEqual([2, 1, 3].sort())
Barrie answered 15/1, 2020 at 11:14 Comment(0)
L
1

What about arrayContaining

expect(value).toEqual(expect.arrayContaining([2, 1, 3]));
Luncheon answered 3/5, 2018 at 11:12 Comment(2)
arrayContaining is similar to what I need. However, arrayContaining allows actual to have additional values that are not in expected. I want to make sure that both arrays contain exactly the same elements, only potentially in different orders.Araxes
Then you have write it by yourself.Orella
H
0

Perhaps you could use the array.sort method to line up the order in conjunction with the arrayContaining method. You might also include a length test for good measure.

const value = [1, 2, 3];
expect(value).toHaveLength(3);
expect(value.sort()).toEqual(expect.arrayContaining(value.sort()));
Holocaust answered 3/5, 2018 at 16:28 Comment(1)
Your second expect tests that value contains its own items. If you're sorting the lists, surely you don't need to also use arrayContaining?Barrie
S
0

A variation on the answer by spoonmeiser that uses the copying version of sort, toSorted().

expect(value.toSorted((a, b) => a - b)).toEqual([1, 2, 3])
Scleroprotein answered 26/1 at 1:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.