Spock: Up and Running

Book description

Most developers would agree that writing automated tests is a good idea, but writing good, well-structured tests is still an elusive skill for many. For Java and Groovy developers, however, there’s good news. This practical guide shows you how to write concise and highly readable tests with Spock, the most innovative testing and specification framework for the JVM since JUnit.

Author Rob Fletcher takes you from Spock basics to advanced topics, using fully worked integration examples. Through the course of this book, you’ll build a simple web application—Squawker—that allows users to post short messages. You’ll discover how much easier it is to write automated tests with Spock’s straightforward and expressive language.

  • Start by learning how to write simple unit tests
  • Understand the lifecycle of Spock specifications and feature methods
  • Dive into interaction testing, using Spock’s intuitive syntax for dealing with mocks and stubs
  • Learn about parameterized tests—writing feature methods that run for multiple sets of data
  • Move into advanced topics, such as writing idiomatic Spock code and driving parameterized tests with file or database input
  • Learn how everything works together in a standalone, fully-worked, test-driven development example

Publisher resources

View/Submit Errata

Table of contents

  1. Introduction
    1. Meet Spock
    2. A Short Background on Groovy
    3. Who Is This Book For?
    4. About This Book
    5. Navigating This Book
    6. Conventions Used in This Book
    7. Using Code Examples
    8. O’Reilly Safari
    9. How to Contact Us
    10. Acknowledgments
  2. I. Spock 101
  3. 1. The “Up and Running” Part
    1. Installation
    2. Running with the JUnit Runner
    3. Running with Gradle
      1. When Groovy Is Used in the Project
      2. Synchronizing Groovy Versions Between Main and Test Classpaths
    4. Running with Maven
  4. 2. Specification Basics
    1. Anatomy of a Specification
      1. Why Use Quoted Strings for Feature Method Names?
    2. An Introduction to Spock’s Blocks
      1. Block Taxonomy
      2. Basic Block Usage
    3. The Specification Lifecycle
      1. Fixture methods: setup and cleanup
    4. Block Descriptions
      1. and: blocks
      2. A Note on Comprehensibility
    5. Summary
      1. Comparison with JUnit
  5. 3. Spock Assertions
    1. The Importance of Good Diagnostics
    2. The Power Assert
      1. Type Information in Power Asserts
    3. Using Groovy for Effective Assertions
      1. Using List Comprehensions and List Literals
      2. Asserting Something About Every Item in a Collection
      3. Expressive Assertions with Groovy Operators
    4. Expecting Exceptions
      1. Interrogating the Exception
    5. Grouping Assertions on the Same Object
    6. Summary
  6. 4. Managing Resources
    1. How (Not) to Approach Persistence Testing
    2. Testing a Persistence Layer
      1. Managing Resources with the Spock Lifecycle
    3. Specifications and Inheritance
      1. Execution Order of Lifecycle Methods in an Inheritance Hierarchy
    4. Summary
  7. 5. Interaction Testing
    1. Asserting that a Method Is Called
    2. Specifying Invocation Cardinality
    3. Declaring the Return Value from a Mocked Method
    4. Parameter Predicates
    5. Disallowing Unexpected Calls or “Strict Mocking”
    6. Looser Matching with Wildcard Parameters
      1. Wildcard Shortcuts
    7. Defining Behavior for Mocked Methods
    8. Removing Invocation Constraints with Stubs
      1. When Should I Use a Mock and When Should I Use a Stub?
      2. Mixing Mocks and Stubs
    9. Summary
  8. 6. Parameterized Specifications
    1. Paramaterization in JUnit
    2. Spock’s where: block
    3. Separating Iteration Reporting by Using @Unroll
      1. Adding @Unroll Descriptions
      2. @Unroll Tokens in Feature Method Names
      3. Class Level @Unroll Annotations
    4. Multiple Data Pipes
    5. Data Tables
    6. Fields and Methods as Data Providers
    7. Derived Values
      1. Clarifying @Unroll Expressions
    8. Summary
  9. II. Advanced Spock
  10. 7. Idiomatic Spock
    1. Organizing Tests
      1. The “Test-per-Method” Antipattern
    2. Well-Factored Specifications
      1. Sharing Helper Methods
      2. Sharing Methods by Using import static
      3. Sharing Methods with Groovy Traits
      4. Sharing Methods with Delegation
      5. Helper Methods and Assertions
      6. Helper Methods and Mock Interactions
      7. Comparing “Before” and “After” Values
    3. The Grammar of Blocks
      1. Separation of Logic and Data with where: Blocks
      2. Using when/then or given/expect
      3. Separating Preconditions
      4. Separating Preconditions from Actions
    4. Method Parameter Capture with Mocks
      1. Using a Closure as a Parameter Predicate
      2. Using Hamcrest for Parameter Predicates
      3. Parameter Capture Using a Mock Responder
    5. @Stepwise Specifications
      1. How to Use @Stepwise
      2. Disadvantages of @Stepwise
    6. Conditional Specifications
      1. Marking Pending Features
      2. Selectively Executing Tests
    7. Automatically Cleaning Up Resources
    8. Documenting Specifications
    9. Summary
  11. 8. Advanced where: Blocks
    1. A Primary Key Verifier
    2. A Static Site Link Checker
      1. JBake Configuration
      2. A Data Pipe Driven by a File
      3. A Filtered Data Pipe
      4. Relative Filepaths
    3. Summary
  12. 9. Asynchronous Testing
    1. Blocking Constructs
      1. BlockingVariable
      2. BlockingVariables
    2. Testing Nonblocking APIs by Using Callbacks
      1. Using BlockingVariable in a Callback
      2. Using a Reference to BlockingVariable.set as a Callback
      3. Awaiting Multiple Values with BlockingVariables
    3. Polling for Eventual State
      1. Using PollingConditions as a Delegate
    4. Asynchronous Interaction Testing
      1. Asynchronous Parameter Capture
      2. Extending BlockingVariable
    5. Summary
  13. 10. Extending Spock
    1. The Message Timeline
    2. Hamcrest Matchers
      1. Hamcrest Support in Spock
    3. JUnit Rules
      1. Reusable Data Cleanup
      2. Simplifying the Rule by Using ExternalResource
      3. Making the Cleanup Logic Generic
    4. Spock Extensions
      1. Data Cleanup as a Spock Extension
      2. Further Steps
    5. Global Extensions
      1. Taking it Further
    6. Summary
  14. 11. Test-Driven Development: The Diamond Kata
    1. The Diamond Kata
    2. Implementation
      1. First Step: The Pathological Case
      2. The Simplest Valid Diamond
      3. Enforcing Invariants
      4. Matrix Content
      5. Symmetry
      6. Eliminating the Assertion Loop
      7. Adding Padding to the Rows
      8. Refinement
    3. Summary
  15. III. Integrating Spock
  16. 12. Spock and Spring
    1. What Do We Mean by “Integration Tests”?
      1. Container Tests
    2. Spring Compatibility
      1. @SpringBootTest
    3. Testing Annotation-Driven Transactions
      1. Tracking Who Is Mentioned in a Message
      2. Non-Spring-Dependent Tests
      3. Testing a Transaction Rollback
      4. Setting Up the Spring Application
      5. A First Integration Test
      6. Convenience and Cost
      7. Unexpected Side Effects
      8. Forcing Spring to Re-Create the Application Context
      9. A Better Way to Force Errors
    4. Mock and Stub Beans
      1. Mention Events
      2. Mock Beans Before Spock 1.1
      3. Mock Bean Delegates
      4. Detached Mocks in the Spring Context
      5. Spring Autoconfiguration and Test Configuration Classes
      6. Mock Beans in XML Configuration
      7. Replacing Application Beans with Mocks
    5. Declarative Test Data
      1. Using the @Sql Annotation for Data Fixtures
      2. Global Fixture Data
      3. Cleaning Up Test Data Spring-Style
    6. Tests in Transactions
      1. Propagated Transactions
    7. Summary
  17. 13. Testing REST APIs
    1. Defining the Application URL
    2. A First Specification
    3. Web Application Lifecycle
    4. Creating Data for End-to-End Tests
      1. Bleeding Data Between Tests
      2. Creating Test Data on Demand
      3. Cleaning Up Test Data
    5. Requests with Data
      1. Fixture Methods
    6. Testing for HTTP Errors
    7. Verifying Response Data
      1. Typed Response Entities
    8. Multiple HTTP Requests in a Feature Method
    9. Backdoors or “Pure” API Testing?
    10. Handling Redirect Responses
      1. Verifying Redirect Details
    11. REST API Security
      1. Authentication versus Authorization
    12. Summary
  18. 14. End-to-End Web Testing
    1. Geb
    2. Getting Started with Geb
    3. A First Frontend Test
    4. Introducing Page Models
      1. Setting the Base URL
      2. Geb’s Automatic Delegation
    5. Authentication
      1. Encapsulating Interactions by Using Methods
    6. Modules
    7. Parameterized Pages
    8. Interacting with Forms
      1. Accessing Form Elements by Name
      2. Encapsulating Interactions with Methods
    9. Form Validation
  19. 15. Testing JavaScript Using Spock
    1. Why Test JavaScript from the JVM?
    2. Setting Up Nashorn for Tests
    3. Calling JavaScript Functions
      1. JavaScript Functions as Objects
      2. Specifying this in a JavaScript Function
    4. Testing an Isomorphic View Component
      1. An Invocable Script Engine as a Delegate
    5. Passing Mocks to JavaScript
    6. Rendering a View with the Handlebars Library
      1. Compiling Handlebars Templates
      2. Testing Template Rendering
      3. Handling Properties That Don’t Convert to JavaScript
      4. Registering Handlebars Helper Functions
      5. Composing Templates with Handlebars Partials
      6. Passing Iterable Values to JavaScript
    7. Summary
  20. 16. Test Driving an RxJava Application
    1. Tests, Behaviors, and Properties
    2. The Skeleton Implementation
    3. Test Driving the Implementation
      1. Defining the Behavior
      2. A First Test
    4. Polling at Regular Intervals
      1. No Sleep `Til the Test Goes Green
      2. Testing Subscription to the Stream
      3. Unchunking the Message Stream
      4. Requesting Messages Since the Last Received
      5. Recovering from Polling Errors
      6. Recovering from Downstream Errors
    5. Final Implementation
  21. A. Groovy Primer
    1. History
    2. Syntactic and Semantic Differences to Java
      1. Semicolons
      2. Import Statements
      3. Class Literals
      4. Visibility
      5. Exceptions
      6. Implicit Return
      7. Default Parameters
      8. Method Dispatch
      9. Valid Java Code That Is Not Valid Groovy Code
    3. Dynamic-Typed Variables
    4. List and Map literals
      1. Lists
      2. Maps
      3. Ranges
      4. Immutability
      5. Maps as Named Arguments
      6. Set and Array Literals
    5. Truthiness
    6. Properties
      1. Accessing Properties
      2. Properties of Java Classes
    7. Strings in Groovy
      1. Templated Strings
      2. Regular Expression Literals
      3. The “Dollar-Slashy” String
      4. Multiline Strings
    8. Operator Overloading
      1. Unary Math Operators
      2. Comparison Operators
      3. Mathematical Operators
      4. Bitwise Operators
      5. Shift Operators
    9. Operators Not Present in Java
      1. Safe Dereference Operator
      2. Call Operator
      3. Subscript Operators
      4. Elvis Operator
      5. Spaceship Operator
      6. Spread Operators
      7. Regular Expression Operators
      8. Field Access Operator
      9. Method Pointer Operator
    10. Operator-Like Keywords
    11. Closures
      1. Defining Closures
      2. Methods That Accept Closures
      3. Closure Delegates
      4. Parameter and Delegate Type Information
      5. Closures and Java 8 Functional Interfaces
    12. The Groovy Development Kit
      1. Functional Iterator Methods
      2. Chained Functional Style
    13. AST Transformations
    14. Summary
  22. Bibliography
  23. Index

Product information

  • Title: Spock: Up and Running
  • Author(s): Rob Fletcher
  • Release date: May 2017
  • Publisher(s): O'Reilly Media, Inc.
  • ISBN: 9781491923290