56

I am getting the following error:

Both assertEquals(Object, Object) in Assert and assertEquals(double, double) in Assert match

For this line of code in my Junit tests, note that getScore() returns a double:

assertEquals(2.5, person.getScore());

This is my assert import:

import static org.junit.Assert.*;

What is causing this and how can I fix this?

java123999
  • 6,974
  • 36
  • 77
  • 121

4 Answers4

58

Your getScore() returns Double, not double. Therefore compiler is confused: Should it convert both arguments to Object, or if it should convert only the Double to double?

    double a = 2.0;
    Double b = 2.0;
    // assertEquals(a,b); // fails to compile
    // the compiler is confused whether to use
    assertEquals((Object) a,(Object) b); // OK
    // or
    assertEquals(a,(double) b); // OK

Anyway, I would set the method to return primitive type double.

Amit Kumar Lal
  • 5,537
  • 3
  • 19
  • 37
Bechyňák Petr
  • 805
  • 9
  • 14
9

If you specifically interested in using Assert.assertEquals(double, double) (the primitive version), try calling overridden method that allows deviation and setting allowed deviation to zero, like this:

assertEquals(2.5, person.getScore(), 0.0);

You might also want to have third parameter to be something other than zero if person.getScore() is allowed to be slightly different from 2.5. For example, if 2.500001 is acceptable, then your test becomes

assertEquals(2.5, person.getScore(), 0.000001);
M. Prokhorov
  • 3,894
  • 25
  • 39
  • 1
    this should be the accepted answer as it does explain the alternative as well as avoiding type cast. – Mohammad Adnan Mar 27 '18 at 18:22
  • @MohammadAdnan I don't think that this suggests a universal solution that doesn't involve type casting. – Romeo Sierra Mar 22 '21 at 03:15
  • @RomeoSierra Please add why do you think it is not a better answer than above. – Mohammad Adnan Mar 22 '21 at 17:29
  • @MohammadAdnan I can give you a counter example. What about `assertEquals(Long expected, Long actual)`? I don't think you have a way around type casting in that case... – Romeo Sierra Mar 23 '21 at 06:24
  • @RomeoSierra, if you have two objects of `Long`, the compiler will resolve to the closest type of `assertEquals(Object, Object)`. If one of those is primitive `long`, then there's indeed no way to avoid a type cast - however, the quesion was about `double`s, not `long`s. – M. Prokhorov Mar 23 '21 at 15:40
  • @M.Prokhorov Well, I have seen otherwise. I have had this exact problem with `Long`, which is how I stumbled upon this question. I am not saying that this is **not a solution**. It does solve the problem. What I am suggesting is that this is **not a universal solution**. – Romeo Sierra Mar 24 '21 at 00:27
  • 1
    @RomeoSierra, it is *a solution* for problem of ambiguous selection between `assertEquals(Object, Object)` and `assertEquals(double, double)`. It is not a solution for ambiguous selection between `assertEquals(Object, Object)`, and `assertEquals(long, long)` (which is in fact its own separate problem entirely) - mainly because there's no method that would accept 3 args. If by "universal" you mean a solution to any kind of problem that involves ambiguous method select, then you are right - in fact, there is **no such solution in existence**, most similar problems are different enough. – M. Prokhorov Mar 25 '21 at 21:16
2

If you specifically want to avoid casting AND use the primitive version, you can get the primitive result from a wrapper object. For example:

    double a = 2.0;
    Double b = 2.0;
    assertEquals(a, b.doubleValue()); //Deprecated so use the one with delta

    Integer c = 2;
    int d = 2;
    assertEquals(c.intValue(), d);

    Long e = 2L;
    long f = 2L;
    assertEquals(e.longValue(), f);
Molten Ice
  • 2,715
  • 1
  • 27
  • 37
0

I had the same error, I changed from this:

assertEquals("Server status code is: " +  wmResp.getStatusCode() , 200, wmResp.getStatusCode());

To this

assertEquals("Server status code is: " +  wmResp.getStatusCode() , Integer.valueOf(200), wmResp.getStatusCode());

This is happening because the first line compiler takes the 200 as primitive (integer not Integer class)

M. Prokhorov
  • 3,894
  • 25
  • 39
JavaSheriff
  • 7,074
  • 20
  • 89
  • 159
  • 1
    We shouldn't suggest people to use constructors of `Integer` and other similar wrapper types. It is marked as deprecated since Java 9, since Java 16 it is [marked for removal](https://openjdk.java.net/jeps/390), and quite soon the constructors will be removed. – M. Prokhorov Mar 23 '21 at 15:47
  • Thank you @Prokhorov Spot on! fixed. – JavaSheriff Mar 23 '21 at 18:33