Another Layer

The fundamental theorem of software engineering in action

September 15, 2021

It's been said that:

We can solve any problem by introducing an extra level of indirection ...except for the problem of too many levels of indirection.

Today I was test-driving a Java component that dealt with an OutputStream. The tests passed in a ByteArrayOutputStream so they could easily inspect the result. All was going well until I realized I wanted to assert that the OutputStream had been closed by the component under test after it was finished writing to it.

Problem: the close method of the ByteArrayOutputStream was a no-op. There was no way to detect the close method by later inspecting the state (or behavior) of the stream.

Solution: add another layer.

import java.io.ByteArrayOutputStream;

public class CloseableSpy extends ByteArrayOutputStream {
    public int Closed;

    public void close() {
        Closed++;
    }
}

Usage example:

OutputStream stream = new ClosableSpy();
new ProductionCodeUnderTest(stream).Invoke();
assertEquals(1, stream.Closed);

Et voilĂ !