开发者

Intercepting JUnit Assert functions

开发者 https://www.devze.com 2023-02-19 07:29 出处:网络
I would like to do some \"own stuff\" when an assertion in JUnit fails. I would like to have this: public class MyAssert extends org.junit.Assert {

I would like to do some "own stuff" when an assertion in JUnit fails. I would like to have this:

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);
    }
}

Of course, this does not work, because you cannot override static methods. But if it would, this would be nice, because every assert function like assertTrue() calls the fail() method. Thus, I could easily intercept eve开发者_如何学Cry assertion.

Does there exist any way to do what I want to do here, without implementing all different flavors of assert...?


You should take a look at the Rules, that were introduced in Junit 4.7. Especially TestWatchman:

TestWatchman is a base class for Rules that take note of the testing action, without modifying it. For example, this class will keep a log of each passing and failing test:

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

It lets you define a MethodRule that can handle failing Tests (Copy from the 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() {
    }

As per comment TestWatchman is depecreated in newer Versions of Junit and replaced with TestWatcher (but the functionality is the same):

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


You could write a class that implements exactly the same signatures of all the methods in Assert and then delegates to the Assert methods.

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);
    }
}

Not exactly re-implementing all the methods, but tedious nonetheless. Your IDE may be able to help in generating the delegate methods.


For indivdual assertions you can catch the AssertionError - the following works for me. It's useful when you only need the functionality occasionally.

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));
}


TestWatchman is replaced with TestWatcher and it intercepts at test method level not Assert level and the Assert class static methods cannot be overridden so an alternative is to create your own assert method to assert objects which should work for most of the asserts

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号