如何为可抛出的负数异常编写完美的代码?使用 assertThatThrownBy

how to write the perfect code for throwable exception a negative number?Using assertThatThrownBy

我有一个单元测试,我想在它上面抛出一个异常(因为它总是会在那个单元测试中抛出)。

我正在尝试使用 try 和 catch,但我不知道之后应该做什么。

在单元测试中(从第一个开始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);
}

我们将抛出该异常的第二个 class。

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());
    }

我在 try 语句中进行了减法运算,并检查减去的数字(新数字)是否为负(-1 或更小)以抛出异常。

我试过了

throw new Throwable(); 

但是没用(可能是我没用好)

我试过了

throw new IllegalArgumentException("Error the Subtracted is in minus...");

在 try 语句中的 if 语句中。 (没有用,我不知道我是否使用正确的方式)。

当调用第二个 class 中的方法时,如果金额为负(-1 或更少),则应抛出异常。

比如我想买一个苹果,我花了2块钱,但我给了他1块钱(1-2 = -1(激活异常)),卖家会拒绝完成付款(Purchase ) 他会 return 给我美元,他会得到苹果。

你的问题出在if条件上:

if (subtractedNumber.intValue() < 0){

此条件会将 BigDecimal 转换为 int,在小数的情况下截断值。在您的情况下,-0.5 将被截断为 0,这就是您的测试未通过的原因。

将此条件更改为

if (subtractedNumber.doubleValue() < 0)

取消对 Illegal Arg Exception 的注释,您的测试将通过。

编辑:添加了更多详细信息

这是我结束的代码:

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);
    }
}

测试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);
    }
}

就我个人而言,我会这样验证异常:

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());
    }
}

两者都按预期工作。