首页 > 解决方案 > 如何为负数的可抛出异常编写完美的代码?使用 assertThatThrownBy

问题描述

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

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

在单元测试中(来自第一堂课)。

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

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

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 语句中。(没有用,我不知道我是否以正确的方式使用)。

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

例如,我想买一个苹果,它花了我 2 美元,但我给了他 1 美元(1-2 = -1(激活异常)),卖方将拒绝完成付款(购买),他将返回给我我的美元,他会得到苹果。

标签: javamavenjunittry-catchassertj

解决方案


您的问题在于 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);
    }
}

测试类:

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

两者都按预期工作。


推荐阅读