© Adam L. Davis 2016

Adam L. Davis, Learning Groovy, 10.1007/978-1-4842-2117-4_14

14. Spock

Adam L. Davis

(1)New York, USA

Spock is a testing framework for Java and Groovy applications. The Spock web site1 has this to say about Spock:

  • What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers. Spock is inspired from JUnit, RSpec, jMock, Mockito, Groovy, Scala, Vulcans, and other fascinating life forms.

Spock Basics

The basic structure of a test class in Spock is a class that extends Specification and has multiple methods with Strings for names.

Spock processes the test code and allows you to use a simple Groovy syntax to specify tests.

Each test is composed of labeled blocks of code with labels like when, then, and where. The best way to learn Spock is with examples.

A Simple Test

Let’s start by recreating a simple test :

1   def "toString yields the String representation"() {
2           def array = ['a', 'b', 'c'] as String[]
3           when:
4           def arrayWrapper = new ArrayWrapper<String>(array);
5           then:
6           arrayWrapper.toString() == '[a, b, c]'
7   }

As shown, assertions are simply groovy conditional expressions. If the == expression returns false, the test will fail and Spock will give a detailed printout to explain why it failed.

In the absence of any when clause, you can use the expect clause instead of then; for example:

1   def "empty list size is zero"() {
2           expect: [].size() == 0
3   }

Mocking

Mocking interfaces is extremely easy in Spock2. Simply use the Mock method, as shown in the following example (where Subscriber is an interface):

1   class  APublisher  extends  Specification {
2     def  publisher = new  Publisher()
3     def subscriber = Mock(Subscriber)

Now subscriber is a mocked object. You can implement methods simply using the overloaded >> operator as shown next. The following example throws an Exception whenever receive is called:

1   def "can cope with misbehaving subscribers"() {
2       subscriber.receive(_) >> { throw   new   Exception() }
3   
4       when:
5       publisher.send("event")
6       publisher.send("event")
7   
8       then:
9       2 * subscriber.receive("event")
10   }

Expected behavior is described by using a number or range multiplied by (*) the method call, as shown here.

The underscore (_) is treated like a wildcard (much like in Scala).

Lists or Tables of Data

Much like how JUnit has DataPoints and Theories, Spock allows you to use lists or tables of data in tests.

For example:

1   def "subscribers receive published events at least once"() {
2       when: publisher.send(event)
3       then: (1.._) * subscriber.receive(event)
4       where: event << ["started", "paused", "stopped"]
5   }

The overloaded << operator is used to provide a list for the event variable. Although it is a list here, anything that is iterable could be used.

Ranges

The range 1.._ here means “one or more” times. You can also use _..3, for example, to mean “three or fewer” times.

Tabular formatted data can be used as well. For example:

1   def "length of NASA mission names"() {
2         expect:
3         name.size() == length
4   
5         where:
6         name       | length
7         "Mercury"  | 7
8         "Gemini"   | 6
9         "Apollo"   | 6
10   }

In this case, the two columns (name and length) are used to substitute the corresponding variables in the expect block. Any number of columns can be used.

Expecting Exceptions

Use the thrown method in the then block to expect a thrown Exception.

1   def "peek on empty stack throws"() {
2       when: stack.peek()
3       then: thrown(EmptyStackException)
4   }

You can also capture the thrown Exception by simply assigning it to thrown(). For example:

1   def "peek on empty stack throws"() {
2       when: stack.peek()
3       then:
4       Exception e = thrown()
5       e.toString().contains("EmptyStackException")
6   }

Summary

As you can see, Spock makes tests more concise and easy to read, and, most importantly, makes the intentions of the test clear.

Footnotes

2 You can also Mock classes, but it requires including the cglib JAR as a dependency.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.117.214