tags:

views:

32

answers:

2

Folks, why I'm getting the "The method assertEquals(String, Object, Object) is ambiguous for the type DictionaryTest" error for this JUnit test?

@Test
 public void testEditCard() {
  Integer a = 10;
  Integer b = 12;
  Integer c = 2;
  assertEquals("test", a-b, c);
 }

Adding casting assertEquals("test", (Integer)(a-b), c); resolves the problem.

+2  A: 

Because of the wonders of autoboxing and -unboxing:

assertEquals("test", /* this is an int */ a-b, /* this is an Integer */ c);

Can be evaluated as

assertEquals(String, long, long);
// in this case the second parameter is unboxed
// (and the first one silently casted)

or as

assertEquals(String, Object, Object);
// in this case the first parameter is boxed

If you declare all variables as int (not Integer), there should be no ambiguity.

seanizer
+2  A: 

It's because the compiler can't tell if you want to call assertEquals(String, Object, Object) or assertEquals(String, long, long). Since a-b and c can be automatically coerced to long the compiler sees an ambiguity.

Your explicit cast tells the compiler that you want the Object version.

Note that in this case you could use int rather than Integer variables which would also fix the ambiguity.

Cameron Skinner
Looking at the JUnit API it seems there is no `assertEquals(String, int, int)` which seems odd...have I missed something? Did the JUnit people really decide to force all `int` checks to be performed using `long`s? Or have I totally misread the API on http://www.junit.org/apidocs/org/junit/Assert.html?
Cameron Skinner
ints can be substituted for longs, just not the other way round.
seanizer
Yes, I know, it just seems like a strange design decision. Integer arithmetic is often faster than long arithmetic, although I guess that will become less relevant as 32-bit systems become less common. I suppose for unit testing efficiency is not so much of an issue.
Cameron Skinner