我得到 .toEqual()
检查普通对象的所有字段的相等性:
expect(
{"key1":"pink wool","key2":"diorite"}
).toEqual(
{"key2":"diorite","key1":"pink wool"}
);
所以这通过了。
但对于数组来说,情况并非如此:
expect(["pink wool", "diorite"]).toEqual(["diorite", "pink wool"]);
在开玩笑的文档中似乎没有匹配器函数来执行此操作,即测试两个数组的相等性,而不管它们的元素位置如何。我是否必须针对另一个数组中的所有元素测试一个数组中的每个元素,反之亦然?还是有其他方法?
没有内置方法可以在不比较顺序的情况下比较数组,但您可以在进行比较之前使用 .sort()
简单地对数组进行排序:
expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());
您可以查看 this fiddle 中的示例。
将元素放入一个集合中。 Jest 知道如何匹配这些。
expect(new Set(["pink wool", "diorite"])).toEqual(new Set(["diorite", "pink wool"]));
["a", "a", "b"]
将匹配 ["a", "b"]
。
如前所述,expect.arrayContaining
检查 actual
数组是否包含 expected
数组作为子集。要检查等效性,可以
要么断言两个数组的长度相同(但这不会导致有用的失败消息)
或断言相反:预期数组包含实际数组:
// 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
中没有的额外元素。
这并不能完全回答这个问题,但仍然可以帮助那些通过谷歌搜索最终到达这里的人:
如果您只关心数组的子集是否包含某些元素,请使用 expect.arrayContaining()
https://jestjs.io/docs/en/expect#expectarraycontainingarray
例如,
expect(["ping wool", "diorite"])
.toEqual(expect.arrayContaining(["diorite", "pink wool"]));
另一种方法是使用来自 jest-community/jest-extended 的自定义匹配器 .toIncludeSameMembers()
。
自述文件中给出的示例
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' }]);
});
仅为一个匹配器导入库可能没有意义,但他们有很多其他有用的匹配器,我发现它们很有用。
您可以使用 this answer 中所述的集合与检查实际结果和期望的长度相结合。这将忽略元素位置并同时保护您免受重复元素的影响。
const materials = ['pink wool', 'diorite'];
const expectedMaterials = ['diorite', 'pink wool'];
expect(new Set(materials)).toEqual(new Set(expectedMaterials));
expect(materials.length).toBe(expectedMaterials.length);
编辑:正如下面评论中所建议的,这仅适用于具有唯一值的数组。
如果要在 JEST 中比较两个数组,请使用波纹管模型。
官方链接:https://jestjs.io/docs/en/expect#expectarraycontainingarray
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));
});
expect(['a','b']).toEqual(expect.arrayContaining(['a']));
,则测试将通过。
检查内容和长度呢?
expect(resultArray).toEqual(expect.arrayContaining(expectedArray));
expect(resultArray.length).toEqual(expectedArray.length);
expected 2 to equal 1
,仅此而已。
如果您没有对象数组,那么您可以在比较之前简单地使用 sort() 函数进行排序。(在接受的答案中提到):
expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());
但是,如果您有对象数组,在这种情况下 sort
函数将不起作用,就会出现问题。在这种情况下,您需要提供自定义排序功能。例子:
const x = [ {key:'forecast',可见:true},{key:'pForecast',可见:false},{key:'effForecast',可见:true},{key:'effRegForecast',可见:true } ] // 在我的用例中,我想按键排序 const sortByKey = (a, b) => { if(a.key < b.key) return -1;否则如果(a.key > b.key)返回 1;否则返回 0; } x.sort(sortByKey) console.log(x)
希望有一天它可以帮助某人。
仍在进行中,但这应该可以工作,但错误消息可能不清楚:
expect.extend({
arrayContainingExactly(receivedOriginal, expected) {
const received = [...receivedOriginal];
if (received.length !== expected.length) return {
message: () => `Expected array of length ${expected.length} but got an array of length ${received.length}`,
pass: false,
};
const pass = expected.every((expectedItem, index) => {
const receivedIndex = findIndex(received, receivedItem => {
if (expectedItem.asymmetricMatch) return expectedItem.asymmetricMatch(receivedItem);
return isEqual(expectedItem, receivedItem);
});
if (receivedIndex === -1) return false;
received.splice(receivedIndex, 1);
return true;
});
return {
message: () => 'Success',
pass,
}
}
});
然后像这样使用它:
expect(['foo', 'bar']).arrayContainingExactly(['foo']) // This should fail
或者
expect({foo: ['foo', 'bar']}).toEqual({
foo: expect.arrayContainingExactly(['bar', 'foo'])
}) // This should pass
我们循环遍历每个值并将其从接收到的数组中删除,以便我们可以利用 Jest 提供的非对称匹配。如果我们只是想做直接等价,这可以简化为只比较 2 个排序数组。
注意:此解决方案使用来自 lodash
的 findIndex
和 isEqual
。