【问题标题】:How to create own annotation for junit that will skip test if concrete exception was thrown during execution?如果在执行期间抛出具体异常,如何为 junit 创建自己的注释,该注释将跳过测试?
【发布时间】:2012-05-29 17:40:17
【问题描述】:

我的应用程序有几种执行模式,在一种模式下,我的一些测试会抛出一个具体的异常是正常的。我需要用 @SkipOnFail 之类的东西来注释这些方法,如果抛出异常,它会将方法设置为已跳过。

提前致谢!

@Edit(让我的问题更清楚)

@Test(expected=ConcreteException.class)

对我不起作用,因为即使未抛出 ConcreteException.class,我也需要通过测试(如果不抛出此异常,junit 中的预期标记会将我的测试标记为失败),否则将被跳过。在所有其他情况下,它应该像往常一样工作。

对我有用的@Solution(junit v4.7)感谢@axtavt

@Rule
public MethodRule skipRule = new MethodRule() {
    public Statement apply(final Statement base, FrameworkMethod method, Object target) {
        if(method.getAnnotation(SkipOnFail.class) == null) return base;

        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try{
                    base.evaluate();
                } catch (ConcreteException e) {
                    Assume.assumeTrue(false);
                }
            }
        };
    }
};

@Thx

【问题讨论】:

  • 为什么不用@Expected jUnit注解呢?
  • 我无法为@Test 方法设置预期的注释属性,因为根据junit javadoc,如果方法没有抛出异常或者如果它抛出与声明的异常不同的异常,则测试失败。但如果没有抛出异常,我需要我的方法成功,如果抛出具体异常,我需要跳过。
  • 你的意思是跳过测试?是被某种方式忽略了还是只是默默地通过了?
  • 为什么不使用带有具体异常的 try catch 块?

标签: java junit4


【解决方案1】:

我不认为这样的功能是开箱即用的,但使用custom TestRuleAssume 应该很容易实现,如下所示:

@Rule
public TestRule skipRule = new TestRule() {
    public Statement apply(final Statement base, Description desc) {
         if (desc.getAnnotation(SkipOnFail.class) == null) return base;

         return new Statement() {
             public void evaluate() throws Throwable {
                 try {
                     base.evaluate();
                 } catch (MyExceptoion ex) {
                     Assume.assumeTrue(false);
                 }
             }
         };
    }
};

【讨论】:

  • 你为什么不直接catch MyException 而不是Throwable
【解决方案2】:

使用JUnit Extensions 怎么样?

以下示例取自他们的Tutorial

它为先决条件(@Prerequisite)提供了额外的注释:忽略基于条件的测试。

所需的方法是在运行测试期间检查这一点。所以你可以简单地添加一个@Prerequisite(requires="")注解。

public class TestFillDatabase {
    @Prerequisite(requires = "databaseIsAvailable")
    @Test public void fillData() {
        // ...
    }

    public boolean databaseIsAvailable() {
        boolean isAvailable = ...;
        return isAvailable;
    }
}
public class TestFillDatabase {
    @Prerequisite(requires = "databaseIsAvailable")
    @Test public void fillData() {
        // ...
    }
    public boolean databaseIsAvailable() {
        boolean isAvailable = ...;
        return isAvailable ;
    }
}

这个带有@Prerequisite(requires = "databaseIsAvailable")的指定方法必须是公共方法,返回一个布尔值或布尔值。

如果将这些方法合并到辅助类中,您还可以在要调用的类中指定静态方法,使用@Prerequisite(requires = "databaseIsAvailable", callee="DBHelper")

public class TestFillDatabase {
    @Prerequisite(requires = "databaseIsAvailable", callee="DBHelper")
    @Test public void fillData() {
        // ...
    }
}
public class DBHelper {
    public static boolean databaseIsAvailable() {
        boolean isAvailable = ...;
        return isAvailable ;
    }
}

【讨论】:

  • 这对我不起作用。如果没有抛出异常,我需要我的测试通过,而不是失败。但如果抛出了一个具体的异常,则应该跳过它。
  • 今天我遇到了一个名为 JUnitExt 的工具包,所以我更新了我的答案,以证明我认为可能是您问题的候选解决方案。
【解决方案3】:

同样使用 Assume 类(自 jUnit 4.4 起),您可以使用assumeNoException()

try{
    base.evaluate();
} catch (ConcreteException e) {
    Assume.assumeNoException("Concrete exception: skipping test", e);
}

【讨论】:

    【解决方案4】:

    我搜索了有关 JUnit 的文档,似乎从 4.9 版开始,他们引入了所谓的测试规则(请参阅TestRule)。你可以从这里开始。

    标记为@RuleExpectedException 类可能有助于检查抛出的异常,但不是强制通过测试。

    对于更高级的用法,我暂时不能说,因为我刚刚发现它。

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      • 1970-01-01
      • 2010-11-27
      • 2014-05-29
      • 2013-08-24
      • 1970-01-01
      相关资源
      最近更新 更多