Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6609251
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T19:41:45+00:00 2026-05-25T19:41:45+00:00

When I’m running a complete test suite, it would be helpful if exceptions that

  • 0

When I’m running a complete test suite, it would be helpful if exceptions that caused a test to fail would appear in my (SLF4J-)log. What is the best method to achieve this?

What I would like

is a junit4 rule that handles exception logging for me. The code

@Rule
public TestRule logException = new TestWatcher() {
    @Override
    public void failed(Description d) {
        catch (Exception e) {
            logger.error("Test ({}) failed because of exception {}", d, e);
            throw e;
        }
    }
}

of course does not work, since I can only catch exceptions out of a try block. Is there a workaround to somehow achieve this in a similarly simple and general way?


BTW, what I’m doing right now

is logging the exception the moment it is created. But it would be nicer to log exceptions at the interface between caller and the library, so in my case in the test case. Not logging when the exceptions are created would also guarantee that they don’t show up multiple times when the caller decides to log them.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T19:41:46+00:00Added an answer on May 25, 2026 at 7:41 pm

    You need to extend TestRule, in particular the apply(). For an example, have a look at org.junit.rules.ExternalResource & org.junit.rules.TemporaryFolder.

    ExternalResource looks like this:

    public abstract class ExternalResource implements TestRule {
        public Statement apply(Statement base, Description description) {
            return statement(base);
        }
    
        private Statement statement(final Statement base) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    before();
                    try {
                        base.evaluate();
                    } finally {
                        after();
                    }
                }
            };
        }
    
        /**
         * Override to set up your specific external resource.
         * @throws if setup fails (which will disable {@code after}
         */
        protected void before() throws Throwable {
            // do nothing
        }
    
        /**
         * Override to tear down your specific external resource.
         */
        protected void after() {
            // do nothing
        }
    }
    

    TemporaryFolder then extends this and implements before() and after().

    public class TemporaryFolder extends ExternalResource {
        private File folder;
    
        @Override
        protected void before() throws Throwable {
            // create the folder
        }
    
        @Override
        protected void after() {
            // delete the folder
        }
    

    So the before gets called before the testMethod, and the after is called in the finally, but you can catch and log any Exception, like:

        private Statement statement(final Statement base) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    before();
                    try {
                        base.evaluate();
                    } catch (Exception e) {
                        log.error("caught Exception", e);
                    } finally {
                        after();
                    }
                }
            };
        }
    

    EDIT: The following works:

    public class SoTest {
        public class ExceptionLoggingRule implements TestRule {
            public Statement apply(Statement base, Description description) {
                return statement(base);
            }
    
            private Statement statement(final Statement base) {
                return new Statement() {
                    @Override
                    public void evaluate() throws Throwable {
                        try {
                            base.evaluate();
                        } catch (Exception e) {
                            System.out.println("caught an exception");
                            e.printStackTrace(System.out);
                            throw e;
                        }
                    }
                };
            }
        }
    
        @Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();
        @Rule public ExpectedException expectedException = ExpectedException.none();
    
        @Test
        public void testMe() throws Exception {
            expectedException.expect(IOException.class);
            throw new IOException("here we are");
        }
    }
    

    The test passes and you get the following output:

    caught an exception
    java.io.IOException: here we are
        at uk.co.farwell.junit.SoTest.testMe(SoTest.java:40)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...
    

    The order that the rules are applied is ExpectedException which calls ExceptionLoggingRule which calls the testMe method. The ExceptionLoggingRule catches the Exception, logs it and rethrows it, and it is then processed by ExpectedException.

    If you want to log only unexpected exceptions, you just switch the declaration order of the rules:

        @Rule public ExpectedException expectedException = ExpectedException.none();
        @Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();
    

    That way, expectedException is applied first (i.e. nested in exceptionLoggingRule), and only rethrows exceptions that are not expected. Furthermore, if some exception was expected and none occured, expectedException will throw an AssertionError which will also get logged.

    This evaluation order isn’t guaranteed, but it is quite unlikely to vary unless you’re playing with very different JVMs, or inheriting between Test classes.

    If the evaluation order is important, then you can always pass one rule to the other for evaluation.

    EDIT: With the recently released Junit 4.10, you can use @RuleChain to chain rules correctly:

    public static class UseRuleChain {
       @Rule
       public TestRule chain= RuleChain
                              .outerRule(new LoggingRule("outer rule")
                              .around(new LoggingRule("middle rule")
                              .around(new LoggingRule("inner rule");
    
       @Test
       public void example() {
               assertTrue(true);
       }
    }
    

    writes the log

    starting outer rule
    starting middle rule
    starting inner rule
    finished inner rule
    finished middle rule
    finished outer rule
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I've got a string that has curly quotes in it. I'd like to replace
I am currently running into a problem where an element is coming back from
I need a function that will clean a strings' special characters. I do NOT
I'm trying to create an if statement in PHP that prevents a single post
I'm working with an upstream system that sometimes sends me text destined for HTML/XML
I would like to count the length of a string with PHP. The string

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.