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

Ben*_*uff 32 jasmine jestjs

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

expect(
    {"key1":"pink  wool","key2":"diorite"}
).toEqual(
    {"key2":"diorite","key1":"pink wool"}
);
Run Code Online (Sandbox Code Playgroud)

这就过去了.

但是对于数组来说也是如此:

expect(["pink wool", "diorite"]).toEqual(["diorite", "pink wool"]);
Run Code Online (Sandbox Code Playgroud)

似乎没有匹配函数在jest docs中执行此操作,即测试两个数组的相等性而不管其元素位置如何.我是否必须针对另一个阵列中的所有元素测试每个元素,反之亦然?或者还有另一种方式吗?

bip*_*obe 44

没有内置方法来比较数组而不比较顺序,但您可以.sort()在进行比较之前简单地对数组进行排序:

expect(["ping wool", "diorite"].sort()).toEqual(["diorite", "pink wool"].sort());`
Run Code Online (Sandbox Code Playgroud)

你可以查看这个小提琴中的例子.

  • 是的,我的意思是你必须根据数据类型为排序函数提供合适的比较器。 (10认同)
  • 如果您使用对象数组,则此方法将不起作用。因为该对象将被转换为[Object object]并且不会被排序。而且您的比较可能仍然失败。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort。 (3认同)

nit*_*zel 21

如前所述,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));
};
Run Code Online (Sandbox Code Playgroud)

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


0xc*_*aff 18

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

expect(new Set(["pink wool", "diorite"])).toEqual(new Set(["diorite", "pink wool"]));
Run Code Online (Sandbox Code Playgroud)

  • 这将忽略重复的值,这可能不是您想要的。`[“ a”,“ a”,“ b”]`将匹配`[“ a”,“ b”]`。 (4认同)
  • 这是在 Jest 23.0.0 中引入的,因此不适用于以前的版本。 (3认同)
  • 不要使用它,因为重复元素不会被计算在内。在你打破头之前避免 (2认同)
  • 我强烈建议您删除这个答案,因为它几乎在所有方面都低于公认的答案。我唯一能想象你的答案会更好的情况是我们有很多重复项,因此之后的比较可能会更快。如果这就是您想说的,请说得更清楚。如果不是,您的答案非常具有误导性,并且可能会对应用程序造成很大的损害,因为它看起来很好并且可以工作直到不再起作用,那么损害可能是巨大的。 (2认同)

jay*_*jay 16

另一种方法是使用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' }]);
});
Run Code Online (Sandbox Code Playgroud)

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


小智 10

检查内容和长度怎么样?

  expect(resultArray).toEqual(expect.arrayContaining(expectedArray));
  expect(resultArray.length).toEqual(expectedArray.length);
Run Code Online (Sandbox Code Playgroud)


Ula*_*ach 7

使用expect.arrayContaining() https://jestjs.io/docs/en/expect#expectarray containsarray

例如,

expect(["ping wool", "diorite"])
  .toEqual(expect.arrayContaining(["diorite", "pink wool"]));
Run Code Online (Sandbox Code Playgroud)

  • 如果数组具有其他值,这不会失败。重点是检查平等。 (10认同)
  • @AndreasHerd是正确的-这个答案不能完全回答这个问题,但是可能会像我一样帮助那些正在寻找这种不受限制的方法的人。 (2认同)
  • 您始终可以测试数组的长度,以确保此测试与预期匹配,而不是预期的子集。 (2认同)

tym*_*zap 5

您可以将使用本答案中所述的集合与检查实际结果和期望的长度结合起来。这将忽略元素位置并同时保护您免受重复元素的影响。

const materials = ['pink wool', 'diorite'];
const expectedMaterials = ['diorite', 'pink wool'];

expect(new Set(materials)).toEqual(new Set(expectedMaterials));
expect(materials.length).toBe(expectedMaterials.length);
Run Code Online (Sandbox Code Playgroud)

编辑:正如下面的评论中所建议的,这仅适用于具有唯一值的数组。


Ser*_*are 5

如果您想在 JEST 中比较两个数组,请使用以下模型。

官方链接:https ://jestjs.io/docs/en/expect#expectarray containsarray

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));
});
Run Code Online (Sandbox Code Playgroud)

  • 请小心 - 顾名思义 - 检查数组是否**包含**另一个数组中的项目。如果您检查其他答案中提到的“expect(['a','b']).toEqual(expect.arrayContaining(['a']));”,则测试将通过。 (2认同)