ChatGPT解决这个技术问题 Extra ChatGPT

Comparing arrays in JUnit assertions, concise built-in way?

Is there a concise, built-in way to do equals assertions on two like-typed arrays in JUnit? By default (at least in JUnit 4) it seems to do an instance compare on the array object itself.

EG, doesn't work:

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

Of course, I can do it manually with:

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

..but is there a better way?


A
Andy Thomas

Use org.junit.Assert's method assertArrayEquals:

import org.junit.Assert;
...

Assert.assertArrayEquals( expectedResult, result );

If this method is not available, you may have accidentally imported the Assert class from junit.framework.


but all you get when it fails for different length is java.lang.AssertionError: array lengths differed, expected.length=6 actual.length=7. As most JUnit failure messages it's not so helpful...I advise using some assertion framework
@user1075613 - I find it helpful. We asserted the arrays were equal, they're not, and we're given an indication why. From there, we can set a breakpoint, and examine the arrays in detail.
right, it's - a bit - helpful. However as you point it out, the instant you have this message you ask yourself "why it's not the same length?" so you want to check the content. Why losing time with a debugger when a good error message could tell it directly? (sure you still need the debugger sometimes but most of the time you don't)
You can submit issues to JUnit's issue tracking system. Bear in mind, though, that 1) failing fast, in O(1), can be an advantage, 2) the assertion failure output should not be O(n). The JUnit issue tracking system is a better forum for further discussion.
@anddero - Assert.assertFalse( Arrays.equals( expectedResult, result )).
B
Bozho

You can use Arrays.equals(..):

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

What stinks about that though is you get NO data about what went wrong when it fails.
Nice when you are on an older junit version (like on Android)
If you want to see which bytes don't match you can convert them to string: assertEquals(Arrays.toString(expectedResult), Arrays.toString(result));
c
csharpfolk

I prefer to convert arrays to strings:

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

this way I can see clearly where wrong values are. This works effectively only for small sized arrays, but I rarely use arrays with more items than 7 in my unit tests.

This method works for primitive types and for other types when overload of toString returns all essential information.


Note, however, that assertEquals( Arrays.toString( new String[]{ "artiforg", "blobel", "kipple", "tench" } ), Arrays.toString( new String[]{ "artiforg", "blobel, kipple", "tench" } ) ); will pass. (The first array consists of three strings, the second of four strings.)
M
Michael Brewer-Davis

Assert.assertArrayEquals("message", expectedResult, result)


Hm, I don't see any 'assertArrayEquals' in my 'junit.framework.Assert'?
4.8.1 is what I have, and what appears to be the latest available via Maven (grepcode.com/…). Is it only in 4.8.2 or 4.9?
P
Pravanjan

JUnit 5 we can just import Assertions and use Assertions.assertArrayEquals method

import org.junit.jupiter.api.Assertions;

Assertions.assertArrayEquals(resultArray,actualResult);

I like this solution
w
winstanr

Using junit4 and Hamcrest you get a concise method of comparing arrays. It also gives details of where the error is in the failure trace.

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

//...

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

Failure Trace output:

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

H
Haroldo_OK

I know the question is for JUnit4, but if you happen to be stuck at JUnit3, you could create a short utility function like that:

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

In JUnit3, this is better than directly comparing the arrays, since it will detail exactly which elements are different.


A
Ankur Agarwal

Class Assertions in org.junit.jupiter.api

Use:

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