Testing

40.1 Power Assert and JUnit

groovy.test.GroovyTestCase / GroovyAssert (shouldFail, assertScript) for JUnit 4 style.

// JUnit 5 with Groovy
import org.junit.jupiter.api.*
import static org.junit.jupiter.api.Assertions.*

class CalculatorTest {
    @Test void addsNumbers() {
        assert 2 + 3 == 5                          // power assert gives a detailed failure output
        assertEquals(5, 2 + 3)
    }
    @Test void throwsOnBadInput() {
        assertThrows(NumberFormatException) { Integer.parseInt("x") }
    }
}

40.2 Spock Framework

Blocks: given/setup, when, then, expect, where, cleanup, and.

Features: data-driven tests, mocks/stubs/spies, interaction verification (n * mock.method(args) >> result), @Shared, @Stepwise, @Timeout, @IgnoreIf, @Requires, @Retry, @PendingFeature, old(), with {}, verifyAll {}, extensions.

Ecosystem: Geb (browser automation with Page Objects), Spock + Testcontainers, spock-reports, Micronaut Test, Grails testing support.

@Grab('org.spockframework:spock-core:2.3-groovy-4.0')
import spock.lang.*

class StackSpec extends Specification {

    def "push adds an element"() {
        given: "an empty stack"
        def stack = new Stack<Integer>()

        when: "an element is pushed"
        stack.push(42)

        then: "the size is one and the top is that element"
        stack.size() == 1
        stack.peek() == 42
    }

    def "pop on empty throws"() {
        when:
        new Stack().pop()
        then:
        thrown(EmptyStackException)
    }

    @Unroll
    def "max of #a and #b is #c"() {
        expect:
        Math.max(a, b) == c

        where:
        a | b || c
        1 | 3 || 3
        7 | 4 || 7
        0 | 0 || 0
    }

    def "mocking a collaborator"() {
        given:
        def repo = Mock(UserRepository)
        def service = new UserService(repo)

        when:
        service.register("ana")

        then:
        1 * repo.save({ it.name == "ana" }) >> new User(id: 1, name: "ana")
        0 * repo.delete(_)
    }

    def "stubbing"() {
        given:
        def repo = Stub(UserRepository) { findById(_) >> new User(name: "stub") }
        expect:
        repo.findById(99).n
…

40.3 Other Testing Tools

Mocking: Spock's built-in mocks, MockFor/StubFor (Groovy's groovy.mock.interceptor), Mockito.

Coverage: JaCoCo (Gradle plugin). Mutation testing: PIT.

Contract and API testing: REST Assured (works great with Groovy), Spring Cloud Contract (Groovy DSL contracts), SoapUI.