portrait

End of Line blog

Thoughts on software development, by Adam Ruka

Specnaz 1.1 released!

I’ve recently released the second version of my test and specification library for Java and Kotlin, Specnaz. Find it on GitHub here:

github.com/skinny85/specnaz

This release contains one new feature: the shouldThrow test method. It’s similar in concept to the expected attribute of JUnit’s @Test annotation: it allows you to declare a test that succeeds only if it throws a particular Exception.

Simple example:

public class StackSpec extends SpecnazJUnit {{
    describes("A Stack", it -> {
        Stack<Integer> stack = new Stack<>();

        it.shouldThrow(EmptyStackException.class, "when popping an empty Stack", () -> {
            stack.pop();
        });
    });
}}

The description of the test will be prefixed with should throw <ExpectedExceptionClass>, so take that into account when writing the test – for instance, the above example will have the description: should throw EmptyStackException when popping an empty Stack.

Another thing is that, just like with JUnit’s @Test(expected = ...), the actual Exception can be of the class of the expected Exception, or it can be a subclass of it; so, the above example could have been also written as:

it.shouldThrow(RuntimeException.class, "when popping an empty Stack", () -> {
    stack.pop();
});

, and it would still pass.

This feature is also available from Kotlin, but works a tiny bit differently in that language. Because Kotlin has reified generics, we can pass the expected Exception class as a type parameter instead of a Class instance, which makes it a little more concise:

class StackSpec : SpecnazKotlinJUnit("A Stack", {
    var stack = Stack<Int>()

    it.shouldThrow<EmptyStackException>("when popping an empty Stack") {
        stack.pop()
    }
})

So, enjoy throwing Exceptions in tests! Let me know what you think of this new feature (and Specnaz in general) in the comments.