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

Jasmine 是否存在忽略jest.js中元素位置的数组相等匹配函数?,jasmine,jestjs,Jasmine,Jestjs,我发现,.toEqual()检查所有字段对于普通对象的相等性: expect( {“key1”:“粉红羊毛”,“key2”:“闪长岩”} )托夸尔先生( {“key2”:“闪长岩”,“key1”:“粉红羊毛”} ); 这样就过去了 但对于阵列,情况并非如此: expect([“粉红羊毛”,“闪长岩])。toEqual([“闪长岩”,“粉红羊毛]); 在jest文档中似乎没有一个matcher函数可以做到这一点,即测试两个数组的相等性,而不管它们的元素位置如何。我是否必须测试一个数组中的每个元

我发现,
.toEqual()
检查所有字段对于普通对象的相等性:

expect(
{“key1”:“粉红羊毛”,“key2”:“闪长岩”}
)托夸尔先生(
{“key2”:“闪长岩”,“key1”:“粉红羊毛”}
);
这样就过去了

但对于阵列,情况并非如此:

expect([“粉红羊毛”,“闪长岩])。toEqual([“闪长岩”,“粉红羊毛]);

在jest文档中似乎没有一个matcher函数可以做到这一点,即测试两个数组的相等性,而不管它们的元素位置如何。我是否必须测试一个数组中的每个元素与另一个数组中的所有元素,反之亦然?或者还有其他方法吗?

没有内置的方法可以在不比较顺序的情况下比较数组,但您可以在进行比较之前使用以下方法对数组进行排序:

expect([“ping wool”,“闪长岩”].sort()).toEqual([“闪长岩”,“粉红羊毛”].sort());

您可以在中查看示例。

这并不能准确回答问题,但仍然可以帮助通过谷歌搜索最终到达此处的用户:

如果您只关心数组的子集是否包含某些元素,请使用
expect.arrayContaining()

e、 g


将元素放入一个集合中。Jest知道如何匹配这些

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

如前所述,
expect.array containing
检查
实际
数组是否包含
预期
数组作为子集。 要检查等效性,可以

  • 或者断言两个数组的长度相同(但这不会产生有用的失败消息)
  • 或者断言相反的结果:
    预期的
    数组包含
    实际的
    数组:
//这是TypeScript,但是删除这些类型,您就可以得到JavaScript
const-expectArrayEquivalence=(实际值:T[],预期值:T[])=>{
expect(实际).toEqual(expect.arrayContaining(预期));
expect(预期).toEqual(预期.数组包含(实际));
};

这仍然存在一个问题,即当测试在第一次断言中失败时,只会让一个人知道
实际
中缺少的元素,而不知道
预期
中没有的额外元素。另一种方法是使用自定义匹配器
。从中包含SameMembers()

自述文件中给出的示例

test('数组以不同顺序匹配时通过',()=>{
期望([1,2,3])包含相同的成员([3,1,2]);
期望([{foo:'bar'},{baz:'qux'}])包含相同的成员([{baz:'qux'},{foo:'bar'}]);
});

仅为一个匹配器导入库可能没有意义,但我发现它们还有很多其他有用的匹配器。

如果您没有对象数组,那么您只需在比较之前使用函数进行排序即可(在接受的答案中提到):

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

const x=[
{key:'forecast',visible:true},
{key:'pForecast',可见:false},
{key:'efffforecast',可见:true},
{key:'effregfecast',可见:true}
]
//在我的用例中,我想按键排序
常数sortByKey=(a,b)=>{
如果(a.keyb.key)返回1;
否则返回0;
}
x、 排序(sortByKey)

console.log(x)
您可以使用中所述的集合与检查实际结果和期望的长度相结合。这将忽略元素位置,同时保护您不受重复元素的影响

const materials=['粉红羊毛','闪长岩'];
预期材料常数=[‘闪长岩’、‘粉红羊毛’];
期望(新的一套(材料))。toEqual(新的一套(期望的材料));
expect(材料.长度).toBe(预期材料.长度);

如果您想开玩笑地比较两个阵列,请使用下面的模型

官方链接:


仍有一项工作在进行中,但这应该可以工作,尽管错误消息可能不清楚:

expect.extend({
阵列精确包含(接收初始,预期){
接收常数=[…接收初始值];
if(received.length!==预期的.length)返回{
消息:()=>`应为长度为${Expected.length}的数组,但获得了长度为${received.length}`的数组,
通过:错误,
};
const pass=expected.every((expectedItem,index)=>{
常量receivedIndex=findIndex(已接收,receivedItem=>{
if(expectedItem.asymmetricMatch)返回expectedItem.asymmetricMatch(receivedItem);
返回isEqual(expectedItem、receivedItem);
});
if(receivedIndex=-1)返回false;
接收。拼接(接收索引,1);
返回true;
});
返回{
消息:()=>“成功”,
通过,
}
}
});
然后像这样使用它:

expect(['foo',bar'])。arrayContainingExactly(['foo'])//这应该失败

expect({foo:['foo',bar']})({
foo:expect.arrayContaining精确(['bar','foo']))
})//这应该通过
我们循环遍历每个值,并将其从接收的数组中删除,以便利用Jest提供的不对称匹配。如果我们只想做直接等价,可以简化为只比较2个排序数组


注意:此解决方案使用
lodash
中的
findIndex
isEqual

如果数组具有附加值,则不会失败。重点是检查是否相等。您可以始终测试数组的长度,以确保此测试符合预期值,而不是预期值的子集。这是在Jest 23.0.0中引入的,因此不适用于以前的版本。这将忽略重复值,这可能不是您想要的<代码>[“a”、“a”、“b”]
将匹配
[“a”、“b”]
。请勿使用此选项,因为重复的元素不会被计算在内。在你打破你的头之前要避免
expect(new Set(["pink wool", "diorite"])).toEqual(new Set(["diorite", "pink wool"]));
expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());
const array1 = ['a', 'b', 'c'];
const array2 = ['a', 'b', 'c'];
const array3 = ['a', 'b'];


it("test two arrays, this will be true", () => { 
    expect(array1).toEqual(expect.arrayContaining(array2));
});

it("test two arrays, this will be false", () => { 
    expect(array3).toEqual(expect.arrayContaining(array1));
});