是否存在忽略jest.js中元素位置的数组相等匹配函数?


72

我得到.toEqual()检查普通对象的所有字段的相等性:

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

这样就过去了。

但是对于数组却不是这样:

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

在jest docs中似乎没有匹配器函数可以执行此操作,即,不管两个数组的元素位置如何,它都测试两个数组是否相等。我是否必须将一个数组中的每个元素与另一个数组中的所有元素进行测试,反之亦然?还是有另一种方法?


还是一个问题,也许我们可以为Jest制作PR?
hypeofpipe

Answers:


85

没有内置方法可以在不比较顺序的情况下比较数组,但是您可以.sort()在进行比较之前简单地使用排序数组:

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

您可以检查这个小提琴中的示例。


波兰排序是最好的
马丁Capodici

13
如果您使用对象数组,则此方法将无效。因为该对象将被转换为[Object object]并且不会被排序。而且您的比较可能仍然失败。developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/…
Avinav

29

将元素放入一组。笑话知道如何匹配这些。

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

2
它是在Jest 23.0.0中引入的,因此不能与以前的版本一起使用。
jkondratowicz

21
这将忽略重复的值,这可能不是您想要的。["a", "a", "b"]将匹配["a", "b"]
Jezzamon

2
请勿使用此选项,因为不会计算重复的元素。在断头之前避免
Jimmy Kane,

15

如前所述,expect.arrayContaining检查actual数组是否包含该expected数组作为子集。为了检查是否等效

  • 要么断言两个数组的长度是相同的(但这不会导致有用的失败消息)
  • 或断言相反:该expected数组包含该actual数组:
// 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));
};

这仍然存在一个问题,即当在第一个断言中测试失败时,只会使您知道缺少的元素,actual而不会知道不在其中的其他元素expected


9

这不能完全回答问题,但仍然可以帮助那些通过Google搜索最终到达这里的人:

如果您只关心数组的子集具有某些元素,请使用expect.arrayContaining() https://jestjs.io/docs/en/expect#expectarray containsarray

例如,

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

22
如果数组具有其他值,这不会失败。重点是检查平等。
安德烈亚斯牧群

1
查看投票结果,看来像我这样的许多人最终都在这里寻找了这个确切的东西!
daemon20年

2
您始终可以测试数组的长度,以确保此测试与期望的结果匹配,而不是期望的子集。
Zakalwe

1

如果没有对象数组,则可以在比较之前简单地使用sort()函数进行排序(在已接受的答案中提到):

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

但是,如果您有对象数组,则在这种情况下sort函数将无法工作时会出现问题。在这种情况下,您需要提供自定义排序功能。例:

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)

希望有一天能对某人有所帮助。


0

您可以结合使用此答案中所述的设置与检查实际结果的长度和期望。这将忽略元素位置,并同时保护您免受重复元素的侵害。


这个想法很好,但是您可以提供一个代码示例来使您的答案更有用吗?
最多
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.