【问题标题】:Expect an exception or one of its subclasses in Junit Test using @Test annotation使用 @Test 注释在 Junit Test 中预期异常或其子类之一
【发布时间】:2012-02-06 18:24:15
【问题描述】:

我有一个预期会出现特定异常的测试,例如:

@Test(expected=MyException.class)
public void testMyMethod(){
    myMethod();
}

myMethod() 方法实际上抛出了MyException 的子类,我们称之为MySubclassException

有没有办法使用@Test 注释定义我的测试以接受MyException 的子类以及类本身?

我知道我可以自己编写测试检查逻辑,而无需使用expected,方法是捕获异常并设置一个标志,但我想知道 JUnit 是否已经支持匹配异常子类。

【问题讨论】:

  • 用户错误的典型案例 - 提示此问题的测试失败,不是因为 JUnit 没有正确匹配异常,而是因为有一个特殊情况下没有抛出需要的异常在测试中处理

标签: java unit-testing junit junit4


【解决方案1】:

框架已经为你处理好了

让我们举一个小例子(非常糟糕的代码): 导入静态 org.junit.Assert.*;

import org.junit.Test;


public class TestExpect {

@Test(expected=MyException.class)
public void test() throws MyException {
    new Foo().foo();
}

}

有 2 个异常类 MyException 和 MyExtendedException 从前一个继承,还有一个像这样的简单 Foo 类:

public class Foo {

public void foo() throws MyException{
    throw new MyExtendedException();
}
}

使用 Eclipse 运行程序启动测试会打印一个绿色条,因为该测试引发了一个 Myexception 实例(是 POO 中的一种关系)

如果您更喜欢阅读源代码,这是来自 Junit 源代码 (ExpectException.java) 的摘录:

   @Override
    public void evaluate() throws Exception {
        boolean complete = false;
        try {
            fNext.evaluate();
            complete = true;
        } catch (AssumptionViolatedException e) {
            throw e;
        } catch (Throwable e) {
            if (!fExpected.isAssignableFrom(e.getClass())) {
                String message= "Unexpected exception, expected<"
                            + fExpected.getName() + "> but was<"
                            + e.getClass().getName() + ">";
                throw new Exception(message, e);
            }
        }
        if (complete)
            throw new AssertionError("Expected exception: "
                    + fExpected.getName());
    }

【讨论】:

  • 我非常讨厌@Test(expected=)。主要原因是单行测试很好,你知道异常来自哪里,但是一旦你有两行并且你想断言第二行抛出异常,你就是 SOL。
【解决方案2】:

如果MyExceptionMySubclassExceptionmyMethod() 抛出,则测试将通过。我用这段代码测试了这个概念:

public class ExceptionTest {

    private static class ExceptionA extends Exception {

    }

    private static class ExceptionB extends ExceptionA {

    }

    @Test(expected=ExceptionA.class)
    public void test() throws Exception {
        throw new ExceptionB();
    }
}

【讨论】:

    【解决方案3】:

    BDD 风格解决方案与Catch Exception

    @Test
    public void testMyMethod() {
    
        when(foo).myMethod();
    
        then(caughtException()).isInstanceOf(MyException.class);
    
    }
    

    依赖关系

    com.googlecode.catch-exception:catch-exception:1.2.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-30
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      相关资源
      最近更新 更多