Spock: Test Well and Prosper

3,988 views

Published on

Demonstrates the basics of the Spock framework for unit testing Java and Groovy applications

0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,988
On SlideShare
0
From Embeds
0
Number of Embeds
24
Actions
Shares
0
Downloads
65
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Spock: Test Well and Prosper

  1. 1. SpockI have been, and always shall be, your friendly testing framework
  2. 2. Who Am I?Ken KousenKousen IT, Inc.http://www.kousenit.comken.kousen@kousenit.com@kenkousenMaking Java Groovyhttp://manning.com/kousen
  3. 3. What is Spock?Testing framework Written in Groovy A logical framework for enterprise testing Combination of Specification + Mock
  4. 4. The Search for SpockSpock home page http://spockframework.org redirects to http://code.google.com/p/spockGithub https://github.com/spockframework/spock
  5. 5. Create a Spock testExtend spock.lang.Specification class MySpec extends Specification
  6. 6. Simple SpecificationDemo: Palindrome Checker
  7. 7. Fixture Methodsdef setup() {} run before every feature methoddef cleanup() {} run after every feature methoddef setupSpec() {} run before first feature methoddef cleanupSpec() {} run after last feature methodLike JUnit 4: @Before, @After, @BeforeClass, @AfterClass
  8. 8. Feature MethodsTest methods def "descriptive name"() { // blocks }
  9. 9. Blockssetup: cleanup:given:when: Stimulusthen: Response, booleans are checkedexpect: where:
  10. 10. when: and then:when: Contents are arbitrarythen: conditions exceptions interactions (mocks described below)Always occur together
  11. 11. what they thought old Kirkold Method would look likeSweet method in Specification class expression value before where block when: obj.count() then: count == old(count) + 1 what he actually looks like
  12. 12. @SharedAnnotation for shared objects Note: instance fields are not shared @Shared res = new VeryExpensiveResource() @Shared sql = Sql.newInstance(...)
  13. 13. @SharedDemo: Library Computer
  14. 14. are exceptions evil or justExceptions goatees?thrown() and notThrown()then: thrown(SqlException) -- or -- SqlException e = thrown() e.sqlCode == ...Can do work after catching exception
  15. 15. Parameterized feature methodsTests that iterate through data Use where: clause expect: name.size() == length where: [name,length] << [[Kirk,4],[Spock,5]]
  16. 16. Data Tablewhere: clause supports data tables expect: name.size() == length where: name | length Shouldnt Data run on Android? Kirk | 4 Spock | 5 McCoy | 5
  17. 17. where: clauseSupports anything Groovy can iterate over expect: x + y == z where: [x,y,z] << sql.rows(select x,y,z from ...)
  18. 18. @UnrollDisplay separate message for each row of dataSpock 0.5: @Unroll({"...$var..."})Spock 0.6+: @Unroll def "my test #var ..."() { ... }
  19. 19. Data SpecsDemos: Hello, Spock! DataDriven DatabaseDriven StadiumLocationsSpec
  20. 20. InteractionsWorking with Mock objects interaction NO KILL I
  21. 21. Creating MocksTwo syntax options: def items = Mock(List) List items = Mock() Can mock interfaces with standard libs Mock classes with CGLIB
  22. 22. Setting ExpectationsUse >> operator list.get(0) >> data
  23. 23. Global vs LocalGlobal: Defined outside then: block Valid to end of feature methodLocal: Defined inside then: block Valid inside preceding when: block
  24. 24. OptionalNo cardinalityMust have return value then: list.get(0) >> data
  25. 25. RequiredMust have cardinalityMay have return value then: 1 * list.get(0) >> data then: 3 * list.size()
  26. 26. CardinalitiesRanges with wildcard Wildcard is _ (underscore) 3 * list.size() // 3 times (3.._) * list.size() // 3 or more (_..3) * list.size() // up to 3
  27. 27. All sorts of constraintsRegex Any set method with one arg pojo./set.*/(_)Nulls, not null pojo.method(!null)
  28. 28. All sorts of constraintsas Operator dir.listFiles(_ as FileFilter)Closures count.increment { it ==~ /a*b/ }
  29. 29. Testing Invocation OrderUse multiple then blocks def testing order of methods() { when: obj.method() then: 1*collaborator.method1() then: 1*collaborator.method2() }
  30. 30. InteractionsDemos: PublisherSubscriber TribbleSpec
  31. 31. Extensions@Timeout@Ignore@IgnoreRest@FailsWith
  32. 32. @FailsWithTest fails with expected exception @FailsWith(TooFewInvocationsError) def "required interaction"() { def m = Mock(List) 2 * m.get(_) >> "foo" expect: m.get(3) == "foo" }
  33. 33. @FailsWithParameters value=ExpectedExceptionOrError reason="reason for failure"
  34. 34. @Ignore and @IgnoreRest@Ignore Dont run a particular test or test class Optional value = reason@IgnoreRest Dont run any OTHER tests
  35. 35. interaction blockMethod in Specification class Takes closure argument def use interaction block() { when: obj.method() then: interaction { // do whatever } }
  36. 36. BDDBehavior 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 threedays" when: "tribbles get into storage compartments" then: "compute number of tribbles" }
  37. 37. Spocks Own TestsLike most modern open source projects Documentation can be thin or outdated Tests are excellent See "smoke" tests in source
  38. 38. Linkshttp://github.com/spockframework/spockhttp://code.google.com/p/spockhttp://spockframework.orghttp://meet.spockframework.orghttp://groups.google.com/group/spockframework?pli=1Source code for examples is from1. spock-example project https://github.com/spockframework/spock-example2. my GitHub repo https://github.com/kousen/Spock-NFJS-Article
  39. 39. Session EvalsPlease complete your session evals

×