【问题标题】:Comparing arrays in JUnit assertions, concise built-in way?比较 JUnit 断言中的数组,简洁的内置方式?
【发布时间】:2011-05-12 19:20:29
【问题描述】:

在 JUnit 中是否有一种简洁的内置方法可以对两个类似类型的数组进行等于断言?默认情况下(至少在 JUnit 4 中)它似乎对数组对象本身进行实例比较。

EG,不起作用:

int[] expectedResult = new int[] { 116800,  116800 };
int[] result = new GraphixMask().sortedAreas(rectangles);
assertEquals(expectedResult, result);

当然,我可以手动完成:

assertEquals(expectedResult.length, result.length);
for (int i = 0; i < expectedResult.length; i++)
    assertEquals("mismatch at " + i, expectedResult[i], result[i]);

..但是有更好的方法吗?

【问题讨论】:

    标签: java arrays junit assertions


    【解决方案1】:

    JUnit 5 我们可以只导入 Assertions 并使用 Assertions.assertArrayEquals 方法

    import org.junit.jupiter.api.Assertions;
    
    Assertions.assertArrayEquals(resultArray,actualResult);
    

    【讨论】:

      【解决方案2】:

      Class Assertions in org.junit.jupiter.api

      用途:

      public static void assertArrayEquals(int[] expected,
                                           int[] actual)
      

      【讨论】:

        【解决方案3】:

        使用 junit4 和 Hamcrest 您可以获得比较数组的简洁方法。它还提供了故障跟踪中错误所在位置的详细信息。

        import static org.junit.Assert.*
        import static org.hamcrest.CoreMatchers.*;
        
        //...
        
        assertThat(result, is(new int[] {56, 100, 2000}));
        

        故障跟踪输出:

        java.lang.AssertionError: 
           Expected: is [<56>, <100>, <2000>]
           but: was [<55>, <100>, <2000>]
        

        【讨论】:

          【解决方案4】:

          我更喜欢将数组转换为字符串:

          Assert.assertEquals(
                          Arrays.toString(values),
                          Arrays.toString(new int[] { 7, 8, 9, 3 }));
          

          这样我可以清楚地看到错误值在哪里。这仅适用于小型数组,但我很少在单元测试中使用超过 7 个项目的数组。

          toString 的重载返回所有基本信息时,此方法适用于原始类型和其他类型。

          【讨论】:

            【解决方案5】:

            我知道问题是针对 JUnit4,但如果您碰巧遇到了 JUnit3,您可以创建一个像这样的简短实用函数:

            private void assertArrayEquals(Object[] esperado, Object[] real) {
                assertEquals(Arrays.asList(esperado), Arrays.asList(real));     
            }
            

            在 JUnit3 中,这比直接比较数组要好,因为它会详细说明哪些元素不同。

            【讨论】:

              【解决方案6】:

              使用org.junit.Assert的方法assertArrayEquals

              import org.junit.Assert;
              ...
              
              Assert.assertArrayEquals( expectedResult, result );
              

              如果此方法不可用,您可能不小心从junit.framework 导入了 Assert 类。

              【讨论】:

              • 但是当它因不同长度而失败时,你得到的只是java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7。作为大多数 JUnit 失败消息,它不是很有帮助...我建议使用一些断言框架
              • @user1075613 - 我觉得它很有帮助。我们断言数组是相等的,但它们不是,并且我们得到了说明原因。从那里,我们可以设置断点,并详细检查数组。
              • 是的,它 - 有点 - 有帮助。但是,正如您所指出的,当您收到此消息时,您会问自己“为什么长度不一样?”所以你想检查内容。当一个好的错误信息可以直接告诉调试器时,为什么还要浪费时间呢? (确定您有时仍然需要调试器,但大多数时候不需要)
              • 您可以将问题提交给JUnit's issue tracking system。但请记住,1) 在 O(1) 中快速失败可能是一个优势,2) 断言失败输出不应该是 O(n)。 JUnit 问题跟踪系统是进一步讨论的更好论坛。
              • @anddero - Assert.assertFalse( Arrays.equals( expectedResult, result )).
              【解决方案7】:

              【讨论】:

              • 嗯,我的“junit.framework.Assert”中没有看到任何“assertArrayEquals”?
              • 4.8.1 是我所拥有的,并且似乎是通过 Maven (grepcode.com/…) 获得的最新版本。仅在 4.8.2 还是 4.9 中?
              【解决方案8】:

              你可以使用Arrays.equals(..):

              assertTrue(Arrays.equals(expectedResult, result));
              

              【讨论】:

              • 这很糟糕的是,当它失败时,你没有得到任何关于出了什么问题的数据。
              • 使用较旧的junit版本(如Android)时很好
              • 如果您想查看哪些字节不匹配,您可以将它们转换为字符串:assertEquals(Arrays.toString(expectedResult), Arrays.toString(result));
              猜你喜欢
              • 2022-12-30
              • 2015-11-04
              • 2015-02-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多