【问题标题】:Exception is never thrown in the corresponding try block在相应的 try 块中永远不会抛出异常
【发布时间】:2018-02-02 13:42:59
【问题描述】:

我有这个方法:

public int addInt(int x, int y){
    try{
        if(x<1 || y<1){
            throw new InvalidValueExeption();
        }
    } catch(InvalidValueExeption i){
        System.out.println(i);
    }
    return x+y;
}

InvalidValueExeption 是一个自定义异常。所以我想测试一下:

@Test
public void test(){
    AddClass a = new AddClass();
    boolean thrown = false;

    try{
        a.addInt(-2, 3);
    } catch(InvalidValueException e){
        thrown=true;
    }

    assertTrue(thrown);
}

我无法运行此测试,因为它显示 Exception exception.InvalidValueException is never thrown in the corresponding try block

我做错了什么?

【问题讨论】:

  • 如果你捕捉到这个异常,addInt 方法如何抛出InvalidValueException 异常?

标签: java exception testing junit


【解决方案1】:

您的 addInt() 方法不会抛出 InvalidValueException (*)。在方法内部,您确实将其抛出,但您在它“离开”您的方法之前将其捕获。所以,对于外界来说,没有InvalidValueException来自你的方法。

然后,编译器正确地告诉您捕获InvalidValueException 是没有意义的。

因此,与其立即在方法中捕获异常,不如声明该方法以抛出 InvalidValueException

public int addInt(int x, int y) throws InvalidValueException {
    if (x < 1 || y < 1) {
        throw new InvalidValueException();
    }
    return x + y;
}

理由:

异常是为了告诉某些方法的调用者 (**) 它无法完成其任务,即您的 addInt() 方法旨在仅添加正数。如果有人用低于 1 的数字尝试它,该方法会以异常回答而不是返回值,因此说:“嘿,出了点问题,所以我不能给你答案(问题描述是 [the其消息等例外])。”


( * ) 我认为,缺少的“c”只是一个错字,并且您没有两个不同的异常类。

( ** ) 这很重要。我不是在谈论System.out.println(),因为这告诉了用户,而不是调用者

【讨论】:

    【解决方案2】:

    如果InvalidValueExeption 是一个检查异常,那么编译器会报错,因为addInt 没有声明为抛出 InvalidValueExeption

    如果InvalidValueExeption 不是已检查异常,则测试将失败,因为addInt 吞下了InvalidValueExeption

    您的问题中也可能存在拼写错误:addInt() throws InvalidValueExeptiontest() 试图捕捉InvalidValueException。在前一种情况下,异常拼写为“Exeption”,在后一种情况下,拼写为“Exception”,注意缺少“c”。

    以下方法可行:

    public int addInt(int x, int y) {
        if (x < 1 || y < 1) {
            throw new InvalidValueException();
        }
    
        return x + y;
    }
    
    @Test(expected = InvalidValueException.class)
    public void test(){
        AddClass a = new AddClass();
    
        a.addInt(-2, 3);
    }
    

    【讨论】:

      【解决方案3】:

      首先我认为您的InvalidValueExeptionRuntimeException 的子类型。

      RuntimeException 及其子类是未经检查的异常。 未经检查的异常不需要在方法中声明或 构造函数的 throws 子句,如果它们可以通过执行 方法或构造函数并在方法之外传播或 构造函数边界。

      因此,如果您需要指示您抛出 InvalidValueExeption 或继承 Exception

      这里在你的方法上声明了异常并抛出:

      public int addInt(int x, int y) throws InvalidValueExeption  {
           try {
              //..
               throw new InvalidValueExeption();
           } catch (InvalidValueExeption e) {
               // do some logging the throw back at you
               throw e;
           }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-05-02
        • 2011-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-01
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多