Jasmine是否有一种测试方法,可以测试2个数组是否包含相同的元素,但不一定按相同的顺序排列?例如:
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
Jasmine是否有一种测试方法,可以测试2个数组是否包含相同的元素,但不一定按相同的顺序排列?例如:
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqualIgnoreOrder(array2);//should be true
编辑
Jasmine 2.8 添加了 arrayWithExactContents
,如果实际值是一个包含样本中所有元素的数组(顺序无关紧要),则会成功。
请参见 keksmasta 的答案
原始(过时)答案
如果只是整数或其他基本类型,你可以在比较之前使用sort()
对它们进行排序。
expect(array1.sort()).toEqual(array2.sort());
如果是对象,则与 map()
函数结合使用,提取将被比较的标识符。array1 = [{id:1}, {id:2}, {id:3}];
array2 = [{id:3}, {id:2}, {id:1}];
expect(array1.map(a => a.id).sort()).toEqual(array2.map(a => a.id).sort());
sort
函数有一个可选的函数参数可以用来进行比较。 - slifty const expected = ['Alice', 'Bob'];
it('matches even if received contains additional elements', () => {
expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
});
expect([1, 2, 3]).toEqual(expect.arrayContaining([3, 3, 3]))
仍然会通过测试,因此不应该使用它。请注意,这只是一个翻译,没有包括任何额外的解释或信息。 - Jordan Burnettjasmine 2.8及以上版本拥有
jasmine.arrayWithExactContents()
期望数组包含列出的元素,顺序不限。
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
jest-extended软件包为我们提供了一些断言来简化测试,它更简洁,并且对于失败的测试,错误更明确。
对于这种情况,我们可以使用toIncludeSameMembers。
expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
简单...
array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayContaining(array2));
// check if every element of array2 is element of array1
// to ensure [1, 1] !== [1, 2]
array2.forEach(x => expect(array1).toContain(x))
// check if every element of array1 is element of array2
// to ensure [1, 2] !== [1, 1]
array1.forEach(x => expect(array2).toContain(x))
// check if they have equal length to ensure [1] !== [1, 1]
expect(array1.length).toBe(array2.length)
.forEach
代替.map
可以节省时间和大量内存。 - Darkhoggarray1 = [1, 2]
,array2 = [1, 1]
。 - redbmk[1,1,2]
和 [1,2,2]
呢?也许可以为每个数组使用 Map 或其他什么东西?例如,对于两个数组都可以使用 array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())
,然后循环遍历它们并检查数量是否相同?这似乎需要很多迭代,但会更彻底。 - redbmkexpect(new Set(a)).toEqual(new Set(b))
//Compare arrays without order
//Example
//a1 = [1, 2, 3, 4, 5]
//a2 = [3, 2, 1, 5, 4]
//isEqual(a1, a2) -> true
//a1 = [1, 2, 3, 4, 5];
//a2 = [3, 2, 1, 5, 4, 6];
//isEqual(a1, a2) -> false
function isInArray(a, e) {
for ( var i = a.length; i--; ) {
if ( a[i] === e ) return true;
}
return false;
}
function isEqArrays(a1, a2) {
if ( a1.length !== a2.length ) {
return false;
}
for ( var i = a1.length; i--; ) {
if ( !isInArray( a2, a1[i] ) ) {
return false;
}
}
return true;
}
这里使用了 forEach 方法来比较每个数组中的每个元素,根据一个唯一的对象属性(这里使用了 status
)。
const expected = [
{ count: 1, status: "A" },
{ count: 3, status: "B" },
];
result.forEach((item) => {
expect(expected.find(a => a.status === item.status)).toEqual(item);
})
expected
中找到的情况。它只断言result
是expected
的一个子集。你需要反过来断言所有expected
的项目都在result
中。 - undefined这里有一个适用于任意数量数组的解决方案。
https://gist.github.com/tvler/cc5b2a3f01543e1658b25ca567c078e4
const areUnsortedArraysEqual = (...arrs) =>
arrs.every((arr, i, [first]) => !i || arr.length === first.length) &&
arrs
.map(arr =>
arr.reduce(
(map, item) => map.set(item, (map.get(item) || 0) + 1),
new Map(),
),
)
.every(
(map, i, [first]) =>
!i ||
[...first, ...map].every(([item]) => first.get(item) === map.get(item)),
);
一些测试(对于具有相同值的多个项的数组,某些答案不予考虑,因此[1、2、2]和[1、2]将错误地返回true)
[1, 2] true
[1, 2], [1, 2] true
[1, 2], [1, 2], [1, 2] true
[1, 2], [2, 1] true
[1, 1, 2], [1, 2, 1] true
[1, 2], [1, 2, 3] false
[1, 2, 3, 4], [1, 2, 3], [1, 2] false
[1, 2, 2], [1, 2] false
[1, 1, 2], [1, 2, 2] false
[1, 2, 3], [1, 2], [1, 2, 3] false
sort
会改变输入数组,尽管这可能不是什么大问题。如果它引起了问题,你可以使用[...array1].sort()
。 - jimmyfever