拦截JUnit Assert函数

时间:2011-03-24 18:18:35

标签: junit interception

当JUnit中的断言失败时,我想做一些“自己的东西”。我想有这个:

public class MyAssert extends org.junit.Assert {

    // @Override
    static public void fail(String message) {
        System.err.println("I am intercepting here!");
        org.junit.Assert.fail(message);
    }
}

当然,这不起作用,因为你无法覆盖静态方法。但如果它会这样,这将是很好的,因为像assertTrue()这样的每个断言函数都会调用fail()方法。因此,我可以轻松拦截每一个断言。

在没有实现assert...的所有不同风格的情况下,有没有办法做我想做的事情?

3 个答案:

答案 0 :(得分:4)

您应该查看Junit 4.7中引入的规则。特别是TestWatchman:

TestWatchman是规则的基类,它注意到测试操作,而不进行修改。例如,此类将记录每次通过和失败的测试:

http://junit-team.github.io/junit/javadoc/4.10/org/junit/rules/TestWatchman.html

它允许您定义可以处理失败测试的MethodRule(从javadoc复制):

   @Rule
    public MethodRule watchman= new TestWatchman() {
            @Override
            public void failed(Throwable e, FrameworkMethod method) {
                    watchedLog+= method.getName() + " " + e.getClass().getSimpleName()
                                    + "\n";
            }

            @Override
            public void succeeded(FrameworkMethod method) {
                    watchedLog+= method.getName() + " " + "success!\n";
            }
    };

    @Test
    public void fails() {
            fail();
    }

    @Test
    public void succeeds() {
    }

根据评论,TestWatchman在较新版本的Junit中被取消,并被TestWatcher取代(但功能相同):

http://junit-team.github.io/junit/javadoc/4.10/org/junit/rules/TestWatcher.html

答案 1 :(得分:1)

您可以编写一个类,该类实现与Assert中所有方法完全相同的签名,然后委托给Assert方法。

public class MyAssert {
    static public void assertTrue(String message, boolean condition) {
        Assert.assertTrue(message, condition);
    }

    ...

    static public void fail(String message) {
        System.err.println("I am intercepting here!");
        Assert.fail(message);
    }
}

不完全重新实施所有方法,但仍然乏味。您的IDE可能有助于生成委托方法。

答案 2 :(得分:0)

对于单个断言,您可以捕获AssertionError - 以下内容适用于我。当你偶尔需要这个功能时它很有用。

try {
    Assert.assertEquals("size", classes.length, containerList.size());
} catch (AssertionError e) {
    System.err.println("ERROR");
    for (AbstractContainer container : containerList) {
        System.err.println(container.getClass());
    }
    throw (new RuntimeException("Failed", e));
}