Watch the Lesson

The text version of this lesson is given in the following:

Introduction to Assertions (aka Conditions)

One difference between Spock Framework and JUnit is that Spock framework doesn’t provide an assertion API. Instead, we can specify the expected state by using conditions. We can write conditions by following these rules:

We have to specify the expected state in the then or expect block.

We can create conditions by using boolean expressions. To be more specific, we can use any expression and Groovy decides whether our expression is true or false.

If our condition is true, our test will pass.

If our condition is false, our test will fail.

If we want to specify conditions outside of the then and expect blocks, we have to use the assert keyword.

We can now create conditions with Spock Framework. Before we will put our new skills into practice, we will take a look at two rules which help us to write feature methods that are easy to read:

We should add the most important conditions to the beginning of the then or expect block and provide a good description to these conditions.

If our conditions belong to different logical groups, we should divide our then or expect block into different sections by using the and label. When we do this, we must provide a good description to the created sections.

Next, we will find out how we can add new conditions to the then and expect blocks.

Writing Assertions in the Then and Expect Blocks

As we already know, we can write assertions by adding new conditions to the then or expect block of our feature method. Let’s take a look at two examples that demonstrate how we can add conditions to our feature methods.

First, let’s write two conditions which verify that our feature method creates an empty list. We can do this by adding a then block to our feature method and adding our conditions to that block.

After we have added a then block to our feature method, the source code of our specification class looks as follows:

By the way, we don’t need both of these conditions. I used these conditions here because I wanted to demonstrate that we can use the return value of a method as a condition or specify the condition by using logical operators.

Second, let’s verify that the max() method of the Math class returns the greater of two numbers. We can do this by adding a new expect block to our feature method and adding our condition to that block.

After we have added a new expect block to our feature method, the source code of our specification class looks as follows:

Let’s move on and find out how we can write assertions for the exceptions thrown by the system under specification.

Writing Assertions for Exceptions

When we want to verify that the when block of our feature method throws an exception, we have to use exception conditions. Next, we will take a look at three examples which demonstrate how we can write assertions for the exceptions thrown by the system under specification.

First, if we want to verify that the when block of our feature method throws a specific exception, we have to use the thrown() method and pass the type of the expected exception as a method parameter.

Let’s write a condition which verifies that the Stack class throws the EmptyStackException if we try to pop an empty stack. After we have written this condition, the source code of our feature method looks as follows:

Second, if we want to verify that the when block of our feature method doesn’t throw a specific exception, we have to use the notThrown() method and pass the type of the exception as a method parameter.

Let’s write a condition which verifies that the Stack class doesn’t throw the EmptyStackException if we try to pop a stack that has one item. After we have written this condition, the source code of our feature method looks as follows:

Third, sometimes we want to write additional assertions for the thrown exception or we want to verify that the state of the system under specification is correct. Spock Framework supports both use cases because exception conditions can be followed by other conditions and other blocks.

Let’s ensure that our when block throws a RuntimeException that has the correct message. We can write the required conditions by following these steps:

Verify that our when block throws a RuntimeException and get a reference to the thrown exception object.

Ensure that the thrown exception has the correct message.

After we have written the required conditions, the source code of our specification class looks as follows:

Using Hamcrest Matchers

Spock Framework allows us to specify conditions by using Hamcrest matchers. This is a good thing because it helps us to write conditions that are easy read, write, and maintain. When we want to write conditions by using a Hamcrest matcher, we have to use this format:

[object or value] [the used Hamcrest matcher]

Let’s verify that our feature method creates a list that has one item. We can write the required conditions by following these steps:

Verify that the created list has one item.

Ensure that the created list contains the correct item.

After we have written the required conditions, the source code of our feature method looks as follows: