Aug 31 2009

JUnit 4 error: reference to assertEquals is ambiguous

Published by at 12:56 pm under Java,JUnit,Testing

This is a somewhat confusing compilation failure that sometimes happen when you write unit tests using JUnit 4. This is an example code snippet that produces this error (result.getValue() returns an Integer object):

assertEquals(12345, result.getValue());

And when you try to compile your project it produces a compilation error like this:

/projects/myapp/src/test/java/org/myapp/MyTest.java:[88,8] reference to assertEquals is ambiguous, both method assertEquals(double,double) in org.junit.Assert and method assertEquals(java.lang.Object,java.lang.Object) in org.junit.Assert match

Since JUnit offer several methods that are very similar the compiler can not always determine which one to use. In our case we have the number 12345 which is an int and result.getValue() which is an Integer. You’d think that the compiler could figure out to convert the number 12345 to an Integer object which would give us a match on “assertEquals(java.lang.Object, java.lang.Object) method, but instead it throws the above error.

The reason for this is that Java uses best match to try to determine the method that will require the least conversion of the parameters. In this case one method requires boxing, and the other method would require un-boxing. Both of these methods have equal priority and that’s why there is ambiguity since none of the methods are more specific than the other.

The solution is to help the compiler determine what it need to do. We can do that using this:

assertEquals(12345, (int) result.getValue());

or this:

assertEquals((Integer)12345, result.getValue());

to resolve this problem. The second solution that converts 12345 to an Integer object is most likely the better once since Java will auto-box a null value to the number 0 which may not be the correct behavior for the class you’re testing.

4 responses so far

4 Responses to “JUnit 4 error: reference to assertEquals is ambiguous”

  1. Virginia says:

    Thank you, thank you. I encountered this problem when I upgraded my JUnit4_4.3.1 to JUnit4_4.5.0. Using the older version, I was comparing “double” to “Double” and the assertEquals(Object, Object) method worked fine. After the upgrade, I received the error you describe above. Your post was very helpful.

    ~ Va

  2. Duran says:

    I have a similar problem but I haven’t come up with a solution yet. This code doesn’t behave as expected with JUnit4_4.5.0:

    assertEquals(“Always fail: “, 0L, 0L);
    assertEquals(“Always OK: “, Long.valueOf(0L), Long.valueOf(0L));

    I haven’t figured out why, and haven’t come up with an acceptable solution either since similar code exists in numerous test cases.

  3. Duran says:

    Finally I have found what I think is the problem. With Eclipse, the delivered JUnit 4.5.0 jar doesn’t behave as the 4.3 version. If I ecplicitly points to the version I have downloaded from JUint.org (a new 4.7 version, not polluted by Eclipse) it works again 🙂

  4. Warren says:

    I am receiving the same error as reported above when I use the is() method.

    assertThat((List)chkList,
    containsInAnyOrder(hasProperty(“quantity”, is((double)qty))));

    Does anyone have an idea how I can fix this issue?

Leave a Reply