Is there an Array equality match function that ignores element position in jest.js?

无人久伴 提交于 2020-07-05 05:16:39

问题


I get that .toEqual() checks equality of all fields for plain objects:

expect(
    {"key1":"pink  wool","key2":"diorite"}
).toEqual(
    {"key2":"diorite","key1":"pink wool"}
);

So this passes.

But the same is not true for arrays:

expect(["pink wool", "diorite"]).toEqual(["diorite", "pink wool"]);

There does not seem to be a matcher function that does this in the jest docs, i.e. that tests for the equality of two arrays irrespective of their elements positions. Do I have to test each element in one array against all the elements in the other and vice versa? Or is there another way?


回答1:


There is no built-in method to compare arrays without comparing the order, but you can simply sort the arrays using .sort() before making a comparison:

expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());`

You can check the example in this fiddle.




回答2:


Put the elements into a set. Jest knows how to match these.

expect(new Set(["pink wool", "diorite"])).toEqual(new Set(["diorite", "pink wool"]));



回答3:


this does not answer the question exactly, but still may help people that end up here by google search:

if you only care that a subset of the array has certain elements, use expect.arrayContaining() https://jestjs.io/docs/en/expect#expectarraycontainingarray

e.g.,

expect(["ping wool", "diorite"])
  .toEqual(expect.arrayContaining(["diorite", "pink wool"]));



回答4:


As already mentioned expect.arrayContaining checks if the actual array contains the expected array as a subset. To check for equivalence one may

  • either assert that the length of both arrays is the same (but that wouldn't result in a helpful failure message)
  • or assert the reverse: That the expected array contains the actual array:
// This is TypeScript, but remove the types and you get JavaScript
const expectArrayEquivalence = <T>(actual: T[], expected: T[]) => {
  expect(actual).toEqual(expect.arrayContaining(expected));
  expect(expected).toEqual(expect.arrayContaining(actual));
};

This still has the problem that when the test fails in the first assertion one is only made aware of the elements missing from actual and no the extra ones that are not in expected.




回答5:


If you don't have array of objects, then you can simply use sort() function for sorting before comparison.(mentioned in accepted answer):

expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());

However, problem arises if you have array of objects in which case sort function won't work. In this case, you need to provide custom sorting function. Example:

const x = [
{key: 'forecast', visible: true},
{key: 'pForecast', visible: false},
{key: 'effForecast', visible: true},
{key: 'effRegForecast', visible: true}
]

// In my use case, i wanted to sort by key
const sortByKey = (a, b) => { 
  if(a.key < b.key) return -1; 
  else if(a.key > b.key) return 1; 
  else return 0; 
  }

x.sort(sortByKey)
console.log(x)

Hope it helps someone someday.




回答6:


You can combine using sets as stated in this answer with checking length of actual result and expectation. This will ignore element position and protect you from duplicated elements in the same time.



来源:https://stackoverflow.com/questions/40135684/is-there-an-array-equality-match-function-that-ignores-element-position-in-jest

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!