Void’s Vault

Knowledge source for efficiency.

Unit Testing an Abstract Class?

Don’t laugh! That may sound curious (or trivial, if you are a true tester), but why would you repeat the tests for the methods of an abstract class into all of its children? Or worst, why would you write the tests for the methods of an abstract class in only one child? That would not be unit tests and if you remove the children, you remove tests duplication, but you leave the abstract class untested. You don’t want that, so here’s a quick how-to guide:

For example, I have a chain of responsibility. The generic behavior of the chainlinks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public abstract class AbstractAnalyserChainOfResponsibility {
    private AbstractAnalyserChainOfResponsibility successor;
    public void setSuccessor(AbstractAnalyserChainOfResponsibility successor) {
        this.successor = successor;
    }

    public Object tryToDoSomething(String aString) throws CannotDoSomethingException {
        if (canDoSomething(aString)) {
            return doSomething(aString);
        } else {
            if (successor != null) {
                return successor.tryToDoSomething(aString);
            } else {
                throw new CannotDoSomethingException("No chain link could handle request");
            }
        }
    }

protected abstract boolean canDoSomething(String aString);
    protected abstract Object doSomething(String aString);
}

Now you just have to test by creating a test class that does the following:

1
2
3
4
5
6
7
8
9
10
11
12
public class TheAbstractClassTest {
private AbstractAnalyserChainOfResponsibility analyzer;
private AbstractAnalyserChainOfResponsibility successor;
private Object manipulatedObject;

@Before
public void setup() {
    manipulatedObject = new Object();
    analyzer = createAnalyzer();
    successor = createSuccessor();
    analyzer.setSuccessor(successor);
}

And then you just have to extend the abstract class this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private AbstractAnalyserChainOfResponsibility createAnalyser() {
        AbstractAnalyserChainOfResponsibility anAnalyser;
        anAnalyser = new AbstractAnalyserChainOfResponsibility() {

            @Override
            protected boolean canDoSomething(String aString) {
                return false; //Or anything you like...
            }

            @Override
            protected Object doSomething(String aString) {
                return new Object(); //Or anything you like....
            }
        };
        return anAnalyser;
    }

Just do the exact same thing for the “createSuccessor” private method of the test class. It’s that easy! Enjoy!