Core Java

Some more unit test tips

In my previous post I showed some tips on unit testing JavaBeans. In this blog entry I will give two more tips on unit testing some fairly common Java code, namely utility classes and Log4J logging statements.

Testing Utility classes

If your utility classes follow the same basic design as the ones I tend to write, they consist of a final class with a private constructor and all static methods.

Utility class tester

package it.jdev.example;

import static org.junit.Assert.*;

import java.lang.reflect.*;

import org.junit.Test;

 * Tests that a utility class is final, contains one private constructor, and
 * all methods are static.
public final class UtilityClassTester {

    private UtilityClassTester() {

     * Verifies that a utility class is well defined.
     * @param clazz
     * @throws Exception
    public static void test(final Class<?> clazz) throws Exception {
        // Utility classes must be final.
        assertTrue("Class must be final.", Modifier.isFinal(clazz.getModifiers()));

        // Only one constructor is allowed and it has to be private.
        assertTrue("Only one constructor is allowed.", clazz.getDeclaredConstructors().length == 1);
        final Constructor<?> constructor = clazz.getDeclaredConstructor();
        assertFalse("Constructor must be private.", constructor.isAccessible());
        assertTrue("Constructor must be private.", Modifier.isPrivate(constructor.getModifiers()));

        // All methods must be static.
        for (final Method method : clazz.getMethods()) {
            if (!Modifier.isStatic(method.getModifiers()) && method.getDeclaringClass().equals(clazz)) {
                fail("Non-static method found: " + method + ".");


This UtilityClassTester itself also follows the utility class constraints noted above, so what better way to demonstrate its use by using it to test itself:

Test case for the UtilityClassTester

package it.jdev.example;

import org.junit.Test;

public class UtilityClassTesterTest {

    public void test() throws Exception {


Testing Log4J logging events

When calling a method that declares an exception you’ll either re-declare that same exception, or you’ll try to deal with it within a try-catch block. In the latter case, the very least you will do is log the caught exception. A very simplistic example is the following:

MyService example

package it.jdev.example;

import java.lang.invoke.MethodHandles;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

public class MyService {

    private static final Logger LOGGER = Logger.getLogger(MethodHandles.Lookup.class);

    private MyRepository myRepository;

    public void doSomethingUseful() {
        try {
        } catch (SomeException e) {
            LOGGER.error("Some very informative error logging.", e);


Of course, you will want to test that the exception is logged appropriately. Something along the line of the following:

Test case for MyService logging event

package it.jdev.example;

import static org.junit.Assert.*;

import org.apache.log4j.spi.LoggingEvent;
import org.junit.*;
import org.mockito.*;

public class MyServiceTest {

    private MyRepository myRepository;

    private MyService myService = new MyService();

    public void setup() {

    public void thatSomeExceptionIsLogged() throws Exception {
        TestAppender testAppender = new TestAppender();


        assertTrue(testAppender.getEvents().size() == 1);
        final LoggingEvent loggingEvent = testAppender.getEvents().get(0);
        assertEquals("Some very informative error logging.", loggingEvent.getMessage().toString());


But how can you go about to achieve this? As it turns out it is very easy to add a new LogAppender to the Log4J RootLogger.

TestAppender for Log4J

package it.jdev.example;

import java.util.*;

import org.apache.log4j.*;
import org.apache.log4j.spi.*;

 * Utility for testing Log4j logging events.
 * <p>
 * Usage:<br />
 * <code>
 * TestAppender testAppender = new TestAppender();<br />
 * classUnderTest.methodThatWillLog();<br /><br />
 * LoggingEvent loggingEvent = testAppender.getEvents().get(0);<br /><br />
 * assertEquals()...<br /><br />
 * </code>
public class TestAppender extends AppenderSkeleton {

    private final List<LoggingEvent> events = new ArrayList<LoggingEvent>();

    public TestAppender() {

    public TestAppender(final Level level) {
        this.addFilter(new LogLevelFilter(level));

    protected void append(final LoggingEvent event) {

    public void close() {

    public boolean requiresLayout() {
        return false;

    public List<LoggingEvent> getEvents() {
        return events;

     * Filter that decides whether to accept or deny a logging event based on
     * the logging level.
    protected class LogLevelFilter extends Filter {

        private final Level level;

        public LogLevelFilter(final Level level) {
            this.level = level;

        public int decide(final LoggingEvent event) {
            if (event.getLevel().isGreaterOrEqual(level)) {
                return ACCEPT;
            } else {
                return DENY;


Reference: Some more unit test tips from our JCG partner Wim van Haaren at the JDev blog.

Want to know how to develop your skillset to become a Java Rockstar?

Join our newsletter to start rocking!

To get you started we give you our best selling eBooks for FREE!


1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design


and many more ....


Receive Java & Developer job alerts in your Area

I have read and agree to the terms & conditions


Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Newest Most Voted
Inline Feedbacks
View all comments
Piotr Dudkiewicz
Piotr Dudkiewicz
9 years ago

My tips:
Testing Utility classes – use static code analysis tool like PMD
Testing Log4J logging events – use Log4jMockPolicy from Powermock

Back to top button