Spock: Test Well and Prosper
- 2. Who Am I?
Ken Kousen
Kousen IT, Inc.
http://www.kousenit.com
ken.kousen@kousenit.com
@kenkousen
Making Java Groovy
http://manning.com/kousen
- 3. What is Spock?
Testing framework
Written in Groovy
A logical framework for enterprise testing
Combination of
Specification + Mock
- 4. The Search for Spock
Spock home page
http://spockframework.org
redirects to
http://code.google.com/p/spock
Github
https://github.com/spockframework/spock
- 5. Create a Spock test
Extend spock.lang.Specification
class MySpec extends Specification
- 7. Fixture Methods
def setup() {}
run before every feature method
def cleanup() {}
run after every feature method
def setupSpec() {}
run before first feature method
def cleanupSpec() {}
run after last feature method
Like JUnit 4:
@Before, @After,
@BeforeClass, @AfterClass
- 9. Blocks
setup: cleanup:
given:
when:
Stimulus
then:
Response, booleans are checked
expect: where:
- 10. when: and then:
when:
Contents are arbitrary
then:
conditions
exceptions
interactions (mocks described below)
Always occur together
- 11. what they thought old Kirk
old Method would look like
Sweet method in Specification class
expression value before
where block
when: obj.count()
then:
count == old(count) + 1
what he actually looks like
- 12. @Shared
Annotation for shared objects
Note: instance fields are not shared
@Shared res = new VeryExpensiveResource()
@Shared sql = Sql.newInstance(...)
- 14. are exceptions evil or just
Exceptions goatees?
thrown() and notThrown()
then:
thrown(SqlException)
-- or --
SqlException e = thrown()
e.sqlCode == ...
Can do work after catching exception
- 16. Data Table
where: clause supports data tables
expect: name.size() == length
where:
name | length Shouldn't Data run on
Android?
'Kirk' | 4
'Spock' | 5
'McCoy' | 5
- 21. Creating Mocks
Two syntax options:
def items = Mock(List)
List items = Mock()
Can mock interfaces with standard libs
Mock classes with CGLIB
- 23. Global vs Local
Global:
Defined outside then: block
Valid to end of feature method
Local:
Defined inside then: block
Valid inside preceding when: block
- 27. All sorts of constraints
Regex
Any set method with one arg
pojo./set.*/(_)
Nulls, not null
pojo.method(!null)
- 28. All sorts of constraints
as Operator
dir.listFiles(_ as FileFilter)
Closures
count.increment { it ==~ /a*b/ }
- 29. Testing Invocation Order
Use multiple then blocks
def 'testing order of methods'() {
when: obj.method()
then: 1*collaborator.method1()
then: 1*collaborator.method2()
}
- 32. @FailsWith
Test fails with expected exception
@FailsWith(TooFewInvocationsError)
def "required interaction"() {
def m = Mock(List)
2 * m.get(_) >> "foo"
expect: m.get(3) == "foo"
}
- 35. interaction block
Method in Specification class
Takes closure argument
def 'use interaction block'() {
when: obj.method()
then:
interaction {
// do whatever
}
}
- 36. BDD
Behavior Driven Development
Each block accepts string description
Just documentation
def "number of tribbles in storage compartment"() {
given: "average litter of 10"
and: "new generation every 12 hours over a period of three
days"
when: "tribbles get into storage compartments"
then: "compute number of tribbles"
}
- 37. Spock's Own Tests
Like most modern open source projects
Documentation can be thin or outdated
Tests are excellent
See "smoke" tests in source