CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/jvm-unit-tests

JVM unit testing (Java / Kotlin / Scala / Groovy) with JUnit 5 (Jupiter) as the primary framework - annotations (`@Test` / `@ParameterizedTest` / source providers), lifecycle hooks (`@BeforeAll` / `@BeforeEach`), extension model (`@ExtendWith` + Mockito/Spring), display names, conditional execution, parallel-execution config, JaCoCo coverage, and Maven Surefire / Gradle CI. Includes a per-language framework decision table (Java → JUnit 5, Kotlin → Kotest, Groovy → Spock, Scala → ScalaTest, legacy → TestNG; always match an existing build convention) and test-authoring conventions (framework detection from pom.xml / build.gradle / build.sbt, path conventions, no fabricated methods). References cover Kotest spec styles, Spock given/when/then + data tables, TestNG DataProviders + suites, ScalaTest styles + Matchers, and the AssertJ fluent-assertion catalog. Use for any JVM unit-test task: choosing or configuring a framework, writing or parameterizing tests, wiring coverage and CI.

72

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

spock.mdreferences/

Spock - Groovy BDD testing (reference)

Companion reference for jvm-unit-tests. Consult for Groovy projects or existing Spock codebases. Pure-Java projects gain little vs JUnit 5 (Spock requires the Groovy compiler in the build); Kotlin teams get more from Kotest (kotest.md).

Per spockframework.org/spock/docs:

Spock's distinguishing features: given/when/then BDD blocks with implicit assertions, where: data tables (the cleanest parametrization syntax on the JVM), and built-in mocking (Mock() / Stub() / Spy() - no Mockito needed) with declarative interaction verification.

Install

build.gradle.kts:

plugins {
    id("groovy")   // Groovy plugin needed for Spock
}

dependencies {
    testImplementation("org.spockframework:spock-core:2.4-M5-groovy-4.0")
    testImplementation(platform("org.junit:junit-bom:5.11.0"))
    testImplementation("org.junit.platform:junit-platform-launcher")
}

tasks.test {
    useJUnitPlatform()   // Spock 2 runs on JUnit Platform
}

Test files: src/test/groovy/**/*Spec.groovy.

Blocks

Per sp-docs:

BlockPurpose
setup: / given:Test fixture setup
when:Action being tested
then:Assertions on the action's effect (each statement is implicitly a boolean assertion)
expect:Combined when+then for simple cases
where:Data table for parametrized tests
cleanup:Per-test cleanup
and:Subdivider for any block
import spock.lang.Specification

class CalculatorSpec extends Specification {
    def "adds two numbers"() {
        given:
        def calc = new Calculator()

        when:
        def result = calc.add(1, 2)

        then:
        result == 3
    }
}

Failure output shows the full expression value, not just true/false.

Data tables

def "addition cases"() {
    expect:
    Calculator.add(a, b) == result

    where:
    a   | b   || result
    1   | 2   || 3
    0   | 0   || 0
    -1  | 1   || 0
}

Each row runs as a separate test; failures don't stop subsequent rows. Exception cases pair thrown() with a piped input list:

then:
InvalidEmailException ex = thrown()

where:
email << ["", "no-at-sign", "@no-domain"]

Built-in mocking

def "user service calls repository"() {
    given:
    def repo = Mock(UserRepository)
    def service = new UserService(repo)

    when:
    service.create("alice@example.com")

    then:
    1 * repo.save(_)   // exactly 1 call to save() with any arg
}

def "service handles repo failure"() {
    given:
    def repo = Stub(UserRepository) {
        save(_) >> { throw new SQLException("connection lost") }
    }
    ...
    then:
    thrown(SQLException)
}

Mock vs Stub vs Spy: Mock() - verifiable interactions; Stub() - no verification, default-value responses unless instructed; Spy() - wraps a real object, observe + optionally override.

Interaction cardinality: 1 * (exactly once), 0 * (never), (1..3) *, 1 * m(_) (any args), 1 * m() >> 42 (stubbed return), 1 * m() >>> [1, 2, 3] (successive returns).

Lifecycle hooks

setupSpec() / cleanupSpec() (once per spec) and setup() / cleanup() (per test).

CI

Spock 2 runs on the JUnit Platform - same shape as JUnit 5: ./gradlew test jacocoTestReport.

Anti-patterns

Anti-patternWhy it failsFix
Mockito alongside SpockTwo mocking APIs in one suiteSpock's built-in mocking
expect: for multi-step setupMixes given + when + thenExplicit given/when/then
_ * cardinality everywhereLoses interaction-count checkSpecify 1 * etc.
Spock for a Java-only projectGroovy adds classpath weightJUnit 5 (SKILL.md)
expect: + where: with no condition expression on the lineBare statements pass silentlyMake the line an expression Groovy evaluates as the assertion

Limitations

  • Requires the Groovy compiler in the build.
  • Groovy syntax learning curve for non-Groovy teams.
  • Spock 2 requires Java 8+ (Spock 1 is end-of-life).

References

  • sp-docs - Spock documentation
  • spockframework.org - landing

SKILL.md

tile.json