Java 使用@Test注释在Junit测试中预期会出现异常或其子类之一

Java 使用@Test注释在Junit测试中预期会出现异常或其子类之一,java,unit-testing,junit,junit4,Java,Unit Testing,Junit,Junit4,我有一个测试需要一个特定的异常,例如: @Test(expected=MyException.class) public void testMyMethod(){ myMethod(); } myMethod()方法实际上抛出了一个子类MyException,我们将其称为MySubclassException 是否可以使用@test注释来定义我的测试,以接受MyException的子类以及类本身? 我知道通过捕获异常并设置标志,我可以自己编写测试检查逻辑,而无需使用expected,但

我有一个测试需要一个特定的异常,例如:

@Test(expected=MyException.class)
public void testMyMethod(){
    myMethod();
}
myMethod()
方法实际上抛出了一个子类
MyException
,我们将其称为
MySubclassException

是否可以使用
@test
注释来定义我的测试,以接受
MyException
的子类以及类本身?


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

这已经由框架为您处理了

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

import org.junit.Test;


public class TestExpect {

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

}
有两个异常类MyException和MyExtendedException继承自上一个异常类,还有一个简单的Foo类,如下所示:

public class Foo {

public void foo() throws MyException{
    throw new MyExtendedException();
}
}
使用Eclipse runner启动测试会打印一个绿色条,因为测试会引发一个Myexception实例(是POO中的一个关系)

如果您更喜欢阅读源代码,这是Junit源代码(ExpectException.java)中的exxcerpt:

@覆盖
public void evaluate()引发异常{
布尔完成=假;
试一试{
fNext.evaluate();
完整=正确;
}捕获(假设违反异常e){
投掷e;
}捕获(可丢弃的e){
如果(!feexpected.isAssignableFrom(e.getClass())){
String message=“意外异常,应为,但为”;
抛出新异常(消息,e);
}
}
如果(完成)
抛出新的断言错误(“预期异常:”
+feexpected.getName());
}

如果
myMethod()
引发了
MyException
MySubclassException
,测试将通过。我用以下代码测试了这个概念:

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();
    }
}
使用样式解决方案 依赖关系
典型的用户错误案例——提示此问题的测试失败了,不是因为JUnit没有正确匹配异常,而是因为有一个特殊的情况,异常没有抛出,需要在testI hate@test(expected=)中处理。主要原因是,对于一行测试来说很好,您知道异常将来自何处,但是一旦您有两行代码,并且您想要断言第二行抛出异常,您就完成了。
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();
    }
}
@Test
public void testMyMethod() {

    when(foo).myMethod();

    then(caughtException()).isInstanceOf(MyException.class);

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