So sánh các mảng trong các xác nhận JUnit, cách dựng sẵn súc tích?


158

Có cách nào ngắn gọn, tích hợp để thực hiện các xác nhận bằng với hai mảng giống như được gõ trong JUnit không? Theo mặc định (ít nhất là trong JUnit 4), nó dường như thực hiện một so sánh trên chính đối tượng mảng.

EG, không hoạt động:

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

Tất nhiên, tôi có thể làm điều đó bằng tay với:

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

.. nhưng có cách nào tốt hơn không?

Câu trả lời:


296

Sử dụng phương thức của org.junit.AssertassertArrayEquals :

import org.junit.Assert;
...

Assert.assertArrayEquals( expectedResult, result );

Nếu phương thức này không có sẵn, bạn có thể đã vô tình nhập lớp Assert từ đó junit.framework.


nhưng tất cả những gì bạn nhận được khi nó thất bại với chiều dài khác nhau là java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7. Vì hầu hết các thông báo lỗi JUnit không hữu ích lắm ... Tôi khuyên bạn nên sử dụng một số khung xác nhận
user1075613

1
@ user1075613 - Tôi thấy nó hữu ích. Chúng tôi khẳng định các mảng bằng nhau, chúng không như vậy và chúng tôi đưa ra một dấu hiệu tại sao. Từ đó, chúng ta có thể thiết lập một điểm dừng và kiểm tra các mảng một cách chi tiết.
Andy Thomas

1
đúng, nó - một chút - hữu ích. Tuy nhiên, khi bạn chỉ ra, ngay lập tức bạn có tin nhắn này, bạn tự hỏi "tại sao nó không cùng độ dài?" vì vậy bạn muốn kiểm tra nội dung Tại sao mất thời gian với trình gỡ lỗi khi một thông báo lỗi tốt có thể nói trực tiếp với nó? (chắc chắn đôi khi bạn vẫn cần trình gỡ lỗi nhưng hầu hết thời gian bạn không dùng)
user1075613

Bạn có thể gửi các vấn đề đến hệ thống theo dõi vấn đề của JUnit . Mặc dù vậy, hãy nhớ rằng 1) thất bại nhanh, trong O (1), có thể là một lợi thế, 2) đầu ra thất bại khẳng định không nên là O (n). Hệ thống theo dõi vấn đề JUnit là một diễn đàn tốt hơn để thảo luận thêm.
Andy Thomas

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

35

Bạn có thể sử dụng Arrays.equals(..):

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

14
Điều tồi tệ về điều đó mặc dù bạn không nhận được dữ liệu về những gì đã sai khi thất bại.
mBria

8
Thật tuyệt khi bạn đang ở phiên bản cũ hơn (như trên Android)
Zitrax 14/12/13

2
Nếu bạn muốn xem byte nào không khớp, bạn có thể chuyển đổi chúng thành chuỗi: assertEquals (Arrays.toString (kỳ vọng), Arrays.toString (kết quả));
Erdem

17

Tôi thích chuyển đổi mảng thành chuỗi:

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

bằng cách này tôi có thể thấy rõ giá trị sai ở đâu. Điều này chỉ hoạt động hiệu quả đối với các mảng có kích thước nhỏ, nhưng tôi hiếm khi sử dụng các mảng có nhiều mục hơn 7 trong các bài kiểm tra đơn vị của mình.

Phương pháp này hoạt động cho các loại nguyên thủy và cho các loại khác khi quá tải toStringtrả về tất cả các thông tin cần thiết.



4

Sử dụng Junit4 và Hamcrest, bạn có được một phương pháp ngắn gọn để so sánh các mảng. Nó cũng cung cấp chi tiết về nơi lỗi nằm trong dấu vết lỗi.

import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*;

//...

assertThat(result, is(new int[] {56, 100, 2000}));

Lỗi đầu ra Trace:

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

2

Tôi biết câu hỏi dành cho JUnit4, nhưng nếu bạn tình cờ bị kẹt tại JUnit3, bạn có thể tạo một chức năng tiện ích ngắn như thế:

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

Trong JUnit3, điều này tốt hơn so với việc so sánh trực tiếp các mảng, vì nó sẽ chi tiết chính xác các yếu tố nào khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.