期望数组无效顺序

Dav*_*ica 57 javascript jasmine karma-jasmine

使用Jasmine有一种方法可以测试2个数组是否包含相同的元素,但不一定是相同的顺序吗?即

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqualIgnoreOrder(array2);//should be true
Run Code Online (Sandbox Code Playgroud)

Kas*_*ars 45

如果它只是整数或其他原始值,那么sort()在比较之前就可以使用它们.

expect(array1.sort()).toEqual(array2.sort());
Run Code Online (Sandbox Code Playgroud)

如果是其对象,则将其与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());
Run Code Online (Sandbox Code Playgroud)

  • @Shmiddty我不知道在这种情况下它是如何重要的.只要两个数组的顺序相同,就应该没问题. (5认同)
  • 该答案的对象部分实际上不会验证对象是否匹配,因为它只是比较映射的数组。您不需要映射,“sort”需要一个可选函数来进行比较。 (4认同)
  • 有道理。不过,值得注意的是,`sort` 就地发生。(它改变了调用它的实例) (3认同)
  • 这不应该是第一个答案,因为它已经过时了。请参阅下面有关 arrayWithExactContents 的答案 (3认同)

小智 36

您可以使用标准玩笑中的 expect.arrayContaining(array) :

  const expected = ['Alice', 'Bob'];
  it('matches even if received contains additional elements', () => {
    expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
  });
Run Code Online (Sandbox Code Playgroud)

  • ```expect([1, 2, 3]).toEqual(expect.arrayContaining([3, 3, 3]))``` 仍然会通过,所以不应该使用它。 (15认同)
  • 对于此用例来说,这不是一个合适的答案,因为问题中的两个数组应该是相等的,只是顺序不同。 (5认同)
  • 它不应该被标记为正确答案,因为它不完整!@enanone (5认同)
  • 有两个问题:1.长度需要检查。Expect(实际长度).toEqual(预期长度); 2.应该是jasmine.array包含的。https://jasmine.github.io/2.6/introduction#section-Partial_Array_Matching_with_%3Ccode%3Ejasmine.arrayContaining%3C/code%3E (3认同)
  • 完美解决方案!这应该是选定的答案.. (2认同)
  • 这是正确的答案。请将其标记为正确答案。@mjarraya 只需测试两个数组的长度是否相同,就可以了。 (2认同)

小智 29

茉莉花 2.8 及更高版本有

jasmine.arrayWithExactContents()
Run Code Online (Sandbox Code Playgroud)

它期望一个数组以任何顺序包含完全列出的元素。

array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))
Run Code Online (Sandbox Code Playgroud)

https://jasmine.github.io/api/3.4/jasmine.html


Jan*_*eck 8

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

  • 使用`.forEach`而不是`.map`来节省一些时间和一堆内存. (2认同)
  • 好赶上@redbmk我为此加了一张支票,谢谢! (2认同)

dav*_*008 8

笑话扩展包为我们提供了一些断言以便简化我们的测试中,它的更简洁和失败的测试误差更加明确。

对于这种情况,我们可以使用toIncludeSameMembers

expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);
Run Code Online (Sandbox Code Playgroud)


小智 7

simple...

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqual(jasmine.arrayContaining(array2));
Run Code Online (Sandbox Code Playgroud)

  • 好答案!您还需要检查长度是否相等,否则对[1,2,3,4]和[3,2,1]会产生误报。 (5认同)

小智 1

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