I have a unit test and I want to throw an exception on it (because it will always throw in that unit test).
I am trying using try and catch but I don't know what should I do after.
In the unit test (from the first class).
@Test
void subtract_money_from_smaller_money_should_fail() {
Money oneDinar = new Money(BigDecimal.valueOf(1));
Money halfDinar = new Money(BigDecimal.valueOf(0.5));
assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
@Override
public void call() throws Throwable {
halfDinar.subtract(oneDinar);
}
}).isInstanceOf(IllegalArgumentException.class);
}
The second class where we will throw that exception.
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= BigDecimal.valueOf(0);
try {
subtractedNumber = current_Money.subtract(new
BigDecimal(String.valueOf(SubtractMoney.current_Money)));
if (subtractedNumber.intValue() < 0) {
// throw new IllegalArgumentException("Error the Subtracted is in minus...");
// throw new Throwable();
}
// System.out.println("TheValue of subtractedNumber" + subtractedNumber.toString());
}
I made subtraction operation inside the try statement, and checked if that subtracted number (the new number) will be in minus (-1 or less) to throw the exception.
I tried this
throw new Throwable();
but didn't work (maybe I didn't use it properly).
I tried this
throw new IllegalArgumentException("Error the Subtracted is in minus...");
inside the if statement in try statement. (didn't work and I don't know if I used in proper way).
When the method in the second class is called, should throw an Exception if the money is in minus (-1 or less).
For example I want to buy an apple and it costs me 2 dollars but I gave him 1 dollar (1-2 = -1 (which activate the exception)), the seller will refuse to complete the payment (Purchase) and he will return to me my dollar and he will get the apple.
Your problem is on the if condition:
if (subtractedNumber.intValue() < 0){
this condition will convert the BigDecimal to int, truncating the value in case of a decimal. In your case, -0.5 will be truncated to 0, and that's why your test is not passing.
Change this condition to
if (subtractedNumber.doubleValue() < 0)
uncomment the Illegal Arg Exception and your test will pass.
Edit: Added more detail
This is the code I ended with:
public class Money {
BigDecimal current_Money;
public Money(BigDecimal money) {
this.current_Money = money;
}
public Money subtract(Money subtractedMoney) {
// TODO: Validation if needed
BigDecimal subtractedNumber = current_Money.subtract(subtractedMoney.current_Money);
if (subtractedNumber.doubleValue() < 0) {
throw new IllegalArgumentException("Error the Subtracted is in minus...");
}
return new Money(subtractedNumber);
}
}
Test class:
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert;
import org.junit.Test;
import java.math.BigDecimal;
public class MoneyTest {
@Test
public void subtract_money_from_smaller_money_should_fail() {
Money oneDinar = new Money(BigDecimal.valueOf(1));
Money halfDinar = new Money(BigDecimal.valueOf(0.5));
Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
@Override
public void call() throws Throwable {
halfDinar.subtract(oneDinar);
}
}).isInstanceOf(IllegalArgumentException.class);
}
}
Personally, I would verify the exception this way:
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
public class MoneyTest {
@Test
public void subtract_money_from_smaller_money_should_fail() {
Money oneDinar = new Money(BigDecimal.valueOf(1));
Money halfDinar = new Money(BigDecimal.valueOf(0.5));
String expectedMessage = "Error the Subtracted is in minus...";
Throwable exception = Assertions.assertThrows(IllegalArgumentException.class, ()
-> {
halfDinar.subtract(oneDinar);
});
Assert.assertEquals(expectedMessage, exception.getMessage());
}
}
Both are working as expected.