เปรียบเทียบ Array ใน JUnit assertions ในตัวแบบรัดกุม?


159

มีวิธีรัดกุมในตัวที่จะทำเท่ากับการยืนยันในสองอาร์เรย์เหมือนพิมพ์ใน 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]);

.. แต่มีวิธีที่ดีกว่า

คำตอบ:


298

ใช้วิธีการorg.junit.AssertassertArrayEquals :

import org.junit.Assert;
...

Assert.assertArrayEquals( expectedResult, result );

junit.frameworkหากวิธีนี้ไม่สามารถใช้ได้คุณอาจได้นำเข้าโดยบังเอิญชั้นยืนยันจาก


java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7แต่ทั้งหมดที่คุณได้รับเมื่อมันล้มเหลวสำหรับความยาวแตกต่างกันคือ เนื่องจากข้อความความล้มเหลวของ JUnit ส่วนใหญ่จะไม่เป็นประโยชน์ ... ฉันแนะนำให้ใช้กรอบการยืนยันบางอย่าง
user1075613

1
@ user1075613 - ฉันพบว่ามีประโยชน์ เรายืนยันว่าอาร์เรย์มีค่าเท่ากัน แต่ไม่ใช่และเรามีข้อบ่งชี้ว่าทำไม จากจุดนี้เราสามารถตั้งค่าเบรกพอยต์และตรวจสอบอาร์เรย์ในรายละเอียด
Andy Thomas

1
ใช่มันเป็นประโยชน์ อย่างไรก็ตามในขณะที่คุณชี้ให้เห็นทันทีคุณมีข้อความนี้คุณถามตัวเองว่า "ทำไมมันไม่ยาวเท่ากัน?" ดังนั้นคุณต้องการตรวจสอบเนื้อหา เหตุใดจึงต้องเสียเวลากับดีบักเกอร์เมื่อเกิดข้อผิดพลาดที่ดีสามารถบอกได้โดยตรง (แน่นอนว่าคุณยังคงต้องใช้ดีบักเกอร์ในบางครั้ง แต่โดยส่วนใหญ่คุณไม่ต้องการ)
user1075613

คุณสามารถส่งประเด็นที่ระบบการติดตามปัญหาของ JUnit โปรดจำไว้ว่า 1) ความล้มเหลวอย่างรวดเร็วใน O (1) สามารถพิจารณาเป็นพิเศษได้ 2) เอาต์พุตความล้มเหลวในการยืนยันไม่ควรเป็น O (n) ระบบติดตามปัญหา JUnit เป็นฟอรัมที่ดีกว่าสำหรับการสนทนาเพิ่มเติม
Andy Thomas

1
@anddero Assert.assertFalse( Arrays.equals( expectedResult, result ))-
Andy Thomas

35

คุณสามารถใช้Arrays.equals(..):

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

14
สิ่งที่คุณคิดเกี่ยวกับสิ่งนั้นแม้ว่าคุณจะไม่ได้รับข้อมูลเกี่ยวกับสิ่งที่ผิดพลาดเมื่อมันล้มเหลว
mBria

8
ดีเมื่อคุณอยู่ในรุ่น junit ที่เก่ากว่า (เช่นบน Android)
Zitrax

2
หากคุณต้องการดูว่าไบต์ใดไม่ตรงกับที่คุณสามารถแปลงเป็นสตริง: assertEquals (Arrays.toString (ที่คาดไว้ Reses)), Arrays.toString (ผลลัพธ์));
Erdem

17

ฉันชอบที่จะแปลงอาร์เรย์เป็นสตริง:

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

ด้วยวิธีนี้ฉันสามารถเห็นได้อย่างชัดเจนว่าค่าที่ผิดคือ สิ่งนี้ทำงานได้อย่างมีประสิทธิภาพสำหรับอาร์เรย์ขนาดเล็กเท่านั้น แต่ฉันไม่ค่อยใช้อาร์เรย์กับรายการมากกว่า 7 ในการทดสอบหน่วยของฉัน

วิธีนี้ใช้ได้กับประเภทดั้งเดิมและประเภทอื่นเมื่อการtoStringส่งคืนข้อมูลที่จำเป็นทั้งหมดเกินพิกัด


11

1
หืมฉันไม่เห็น 'assertArrayEquals' ใน 'junit.framework.Assert' ของฉัน?
mBria

4.8.1 คือสิ่งที่ฉันมีและสิ่งที่ดูเหมือนจะเป็นล่าสุดที่มีอยู่ผ่าน Maven ( grepcode.com/… ) มันอยู่ใน 4.8.2 หรือ 4.9 เท่านั้น?
mBria

4

การใช้ 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>]

2

ฉันรู้ว่าคำถามสำหรับ JUnit4 แต่ถ้าคุณบังเอิญติดที่ JUnit3 คุณสามารถสร้างฟังก์ชั่นยูทิลิตี้แบบสั้น ๆ เช่นนั้น:

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

ใน JUnit3 จะเป็นการดีกว่าการเปรียบเทียบอาร์เรย์โดยตรงเนื่องจากจะให้รายละเอียดที่แน่นอนว่าองค์ประกอบใดแตกต่างกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.