Search code examples
javamavenintellij-ideajunitmaven-plugin

Why is comparing same objects values using if statement or assertj always gives error?


I subtracted two Objects using another class, but when I return the new value and compare to the expected value, it's gives error even when it's the same value(I think).

I tried to use if statement but same thing.

   if(expected.current_Money.toString().equals(0.5)){
        System.out.println(" if statmenet is working...");

    }
    else
    {
        System.out.println("failed");
    }

Imports in that first class(Prefer not to change it).

   import org.assertj.core.api.ThrowableAssert;
   import org.junit.jupiter.api.Test;
   import java.math.BigDecimal;

   import static org.assertj.core.api.Assertions.assertThat;
   import static org.assertj.core.api.Assertions.assertThatThrownBy;

On the same file, we have this method.

@Test
void subtract_two_money_should_be_correct() {
    Money oneDinar = new Money(BigDecimal.valueOf(1));
    Money halfDinar = new Money(BigDecimal.valueOf(0.5));
    System.out.println("Value of oneDinar 
    "+oneDinar.current_Money.toString());
    System.out.println("Value of halfDinar 
    "+halfDinar.current_Money.toString());

    //Money expected = oneDinar.subtract(halfDinar);
    Money expected = new Money(BigDecimal.valueOf(0.5));

    System.out.println("the Value of Expected 
    "+expected.current_Money.toString());

    assertThat(expected).isEqualTo(new Money(BigDecimal.valueOf(0.5)));
}

The output of subtracted is saved to an object and have variable inside has datatype BigDecimal .

On the other file. Imports

import java.math.BigDecimal;

We have these fields(variables inside the second class.

    public static final Money HALF_DINAR = new 
  Money(BigDecimal.valueOf(0.5));


    public static final Money QUARTER_DINAR = new 
  Money(BigDecimal.valueOf(0.25)) ;
    public static final Money DINAR = new Money(BigDecimal.valueOf(1));
    public BigDecimal current_Money;

Here is the last thing, the method we used to subtract.

  public Money subtract(Money SubtractMoney) {
            System.out.println("TheValue of current money "+current_Money.toString());
            Money current = new Money(current_Money);
            System.out.println("TheValue of current  "+current.current_Money.toString());

            BigDecimal subtractedNumber = current_Money.subtract(new BigDecimal(String.valueOf(SubtractMoney.current_Money)));
            System.out.println("TheValue of subtractedNumber"+subtractedNumber.toString());

            Money newMoney = new Money(subtractedNumber);
            System.out.println("TheValue of newMoney "+newMoney.current_Money.toString());

            return newMoney ;
        }

I expect the output will be same as that object(in numbers is the same, but it's give me wrong even if i used if statement or Assertthat.

I expect output is true and no errors. also the number is 0.5 which is the goal.

Output:

Value of oneDinar 1
Value of halfDinar 0.5
TheValue of current money 1
TheValue of current  1
TheValue of subtractedNumber0.5
TheValue of newMoney 0.5
the Value of Expected 0.5

org.opentest4j.AssertionFailedError: 
Expecting:
 <com.progressoft.induction.Money@123f1134>
to be equal to:
 <com.progressoft.induction.Money@7d68ef40>
but was not.
Expected :com.progressoft.induction.Money@7d68ef40
Actual   :com.progressoft.induction.Money@123f1134

Solution

  • The isEqualTo(...) function of AssertJ uses the objects equals method internally to determine equality. Therfore you should override the equals() method in your Money class. Then you can compare the instances by content instead of object identity, i.e. if the value is the same the instances are considered equal.

    The comparison in your if (expected.current_Money.toString().equals(0.5)) statement doesn't work, because the expected.current_Money.toString() part is a string and the 0.5 is auto-boxed to a Double object. Therefore the equals comparison fails because the classes are different.

    Side note: Whenever you override the equals() method you also need to override the hashcode() function to match the equals() function. Otherwise many classes (e.g. HashMap) might misbehave, because they assume that equals and hashcode work based on the same assumptions.