Spock

Spock
Jakub Háva, jakub.hava@gmail.com
What is Spock
● Testing and specification framework for Java
and groovy applications
● Uses JUnit
● Powered by Groovy
Specification
● Different name for class with tests
● Regular Groovy classes extending
specification class
● Specification class is a JUnit class
Instance fields
● Part of the specification
● They are not shared between feature
methods
● Every test method gets its own object
● Example: def coll = new Collaborator()
Special fields
@Shared res = new VeryExpensiveResource()
● This field is shared amongst the feature
methods
static final PI = 3.141592654
● Static fields should be used just for
constants
Fixture methods
def setup() {}
● run before every feature method
def cleanup() {}
● run after every feature method
Fixture methods
def setupSpec() {}
● run before the first feature method
def cleanupSpec() {}
● run after the last feature method
Feature methods
● Regular test methods
● Consist of blocks
def "pushing an element on the stack"() {
// blocks go here
}
Feature methods - phases
● Set up the feature's fixture
● Provide a stimulus to the system under
specification
● Describe the response expected from the
system
● Clean up the feature's fixture
Feature methods - phases
● Phase 1 and 4 are optional
● Phase 2 and 3 can occur more than once
Blocks
● Six kinds of blocks: setup, when, then,
expect, cleanup, and where blocks
● Can not be nested
Blocks mapping to phases
Setup blocks
setup:
def stack = new Stack()
def elem = "push me"
● Optional
● Has to be first, can not be repeated
● Given is just alias to setup label
When and then blocks
when: // stimulus
then: // response
● Occur together
● When block may contain arbitrary code
● Then block may consist of conditions,
exception conditions, interactions and
variable definitions
Conditions
● Like JUnit assertion
when:
stack.push(elem)
then:
!stack.empty
stack.size() == 1
stack.peek() == elem
Conditions - result
Condition not satisfied:
stack.size() == 2
| | |
| 1 false
[push me]
Exception Conditions
when:
stack.pop()
then:
EmptyStackException e = thrown()
e.cause == null
Exception conditions
● Use notThrown(Exception) when exception
should not be thrown
Interaction
● Condition describe object state, but
interaction describe communication between
components
● Used for mocking
Interactions: Creating Mocks
● Mocks can be created for java interfaces,
java non-final classes and groovy non-final
classes
def subscriber = Mock(Subscriber)
Subscriber subscriber = Mock()
subscriber.isActive() >> true
Except block
● May contain only conditions and variables
● Useful when stimulus and expected
response should be one expression
● Guideline: use when-then for methods with
side effects, except for purely functional
methods
Except block - example
when:
def x = Math.max(1, 2)
then:
x == 2
VS
expect:
Math.max(1, 2) == 2
Cleanup blocks
● Has to be after where block
setup:
def file = new File("/some/path")
file.createNewFile()
// ...
cleanup:
file.delete()
Where block
● Last block in the method
● It is used to write data-driven feature
methods
Where block - example
def "computing the maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a << [5, 3]
b << [1, 9]
c << [5, 9]
}
Specification as Documentation
● Spock allows to attach documentation to
blocks
● and: label is just used for documentation
purposes
Spec as Documentation - Example
setup: "open a database connection"
// code goes here
and: "seed the customer table"
// code goes here
and: "seed the product table"
// code goes here
Extensions directives 1
@Timeout
● Sets a timeout for execution of a feature or
fixture method.
@Ignore
● Ignores a feature method.
Extension directives 2
@IgnoreRest
● Ignores all feature methods not carrying this
annotation. Useful for quickly running just a
single method.
@FailsWith
● Expects a feature method to not complete
correctly.
Simple Parametrization
● Simple parametrization of feature methods
where:
x << dataProvider
def "test me"(int x) {
// ...
where: x << [1,2,3]
}
Derived Parametrization
● Derived from already existing data
where:
row << sql.execute("select * from customer")
firstName = row["first_name"]
secondName = row["second_name"]
name = firstName + " " + secondName
Multi Parametrization
where:
[name, age, gender] = sql.execute("select
name, age, sex from customer")
where:
[name, _, gender] = sql.execute("select
name, age, sex from customer")
IDE Integration
● Eclipse
● IntelliJ
● Netbeans
Spock Web Console & Examples
● http://meetspock.appspot.com/
● https://github.com/spockframework/spockexample
References
https://code.google.com/p/spock/wiki/SpockBasics
http://blog.andresteingress.com/2013/10/29/spockmocking-and-stubbing/
https://code.google.com/p/spock/wiki/WhySpock
http://java.dzone.com/articles/introduction-spock
Thank you
Any questions ?