{"id":28304287,"url":"https://github.com/mkutz/spock-testing-workshop","last_synced_at":"2026-03-06T16:02:32.329Z","repository":{"id":38361916,"uuid":"75164580","full_name":"mkutz/spock-testing-workshop","owner":"mkutz","description":"Workshop for testing Java projects with Spock and Groovy.","archived":false,"fork":false,"pushed_at":"2026-02-23T07:41:23.000Z","size":316,"stargazers_count":10,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-23T15:49:22.322Z","etag":null,"topics":["pom","spock","testing","workshop"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkutz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-11-30T07:56:48.000Z","updated_at":"2026-02-23T07:40:12.000Z","dependencies_parsed_at":"2025-12-08T09:09:33.152Z","dependency_job_id":null,"html_url":"https://github.com/mkutz/spock-testing-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mkutz/spock-testing-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkutz%2Fspock-testing-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkutz%2Fspock-testing-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkutz%2Fspock-testing-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkutz%2Fspock-testing-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkutz","download_url":"https://codeload.github.com/mkutz/spock-testing-workshop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkutz%2Fspock-testing-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30184876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T14:42:24.748Z","status":"ssl_error","status_checked_at":"2026-03-06T14:42:14.925Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pom","spock","testing","workshop"],"created_at":"2025-05-24T00:12:34.671Z","updated_at":"2026-03-06T16:02:32.303Z","avatar_url":"https://github.com/mkutz.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spock Testing Workshop [![Build](https://github.com/mkutz/spock-testing-workshop/actions/workflows/build.yml/badge.svg)](https://github.com/mkutz/spock-testing-workshop/actions/workflows/build.yml)\n\nWorkshop for testing Java projects with [Spock] and [Groovy].\n\n\n## Project Setup with Maven\n\nIn order to get [Spock] into our Maven project, we need to do the following in our [pom.xml].\n\n1. Add Groovy and Spock as (test) dependencies (see [pom.xml](pom.xml#L41-L46)) and (see [pom.xml](pom.xml#L48-L52)).\n   Note that the version tags can be omitted due to the dependency management (see [pom.xml](pom.xml#L21-L39)).\n2. Add ByteBuddy and Objenesis in order to be able to Mock classes (see [pom.xml](pom.xml#L54-L70)).\n3. Make Maven aware of `/src/test/groovy` being a test source directory since Maven’s default is `/src/test/java` (see [pom.xml](pom.xml#L88-L89)).\n4. Add the [GMavenPlus] plugin, to compile your Groovy sources and configure the maven-compiler-plugin (see [pom.xml](pom.xml#L92-L115)).\n5. Make Maven Surefire plugin aware of files ending with `*Spec` are test class files since Surefire’s default is `*Test` (see [pom.xml](pom.xml#L117-L128)).\n\n\n## Project Setup with Gradle\n\nIn order to get [Spock] into our Gradle project, we need to do the following in our [build.gradle].\n\n1. Add the Groovy plugin (see [build.gradle](build.gradle#L3)).\n2. Add Groovy as a `testImplementation` dependency (see [build.gradle](build.gradle#L12)).\n3. Add Groovy and Spock dependency (see [build.gradle](build.gradle#L12-L16)).\n4. Add ByteBuddy and Objenesis in order to be able to Mock classes (see [build.gradle](build.gradle#L18-19)).\n5. Configure Gradle to use JUnit 5 (see [build.gradle](build.gradle#L27-29))\n\n\n## Part 1: Blocks, Expectations and Pending Features\n\nRead the [Spock Primer section] of the [Spock Framework Reference Documentation] to learn about the basic [Spock] terminology, fixture and feature methods, blocks and expectations.\n\nI personally don't like block comments to stay in the test after it has been implemented (as suggested in the [Specifications as Documentation section]) for I want the *code* to be self-explanatory.\nHence, in this workshop we won't use that feature.\n\nThen try to do the following objectives:\n\n- [ ] The method `isOfAge` method in [User] is not implemented properly yet.\n  However, there is a test in [UserClassSpec] which is annotated with `@PendingFeature`.\\\n  Use the commented out code in `isOfAge`, in order to make the test's expectation be true.\n  Once you did, remove the annotation.\n- [ ] The feature methods uses `given`, `when` and `then`.\n  Try to make it shorter using an `expect` block.\n- [ ] Our current implementation of [User] allows to create users who were not born yet.\n  Write a `@PendingFeature` that expects that `\"creating a user with a future birthday throws an IllegalArgumentException\"`.\n- [ ] Adjust [User] to make the feature no longer pending and remove the annotation.\n- [ ] Write another feature method that specifies that `\"no exception in thrown if the birthday is in the past\"`.\n\n\n## Part 2: Data Driven Testing\n\nRead the [Data Driven Testing section] of the [Spock Framework Reference Documentation] to learn about `where` blocks and their data table and pipe notations and the `@Unroll` annotation.\n\nThen try to do the following objectives:\n\n- [ ] You might have noticed, that the implementation of `isOfAge` is not really how its name suggests because not only users are of age whose 18th birthday is today!\n  Write another feature method to ensure that `\"isOfAge should return true if the user's birthday is more than 18 years ago\"`.\n  Use a `where` block to test several cases.\n- [ ] Use [Unrolled Iteration Names] to get better test result output.\n- [ ] Add another data driven test `\"isOfAge should return false if the user's birthday is less than 18 years ago\"` to test negative cases.\n- [ ] Review your features and try to make more test data driven.\n\n\n## Part 3: Mocking and Stubbing\n\nRead the [Interaction Based Testing section] of the [Spock Framework Reference Documentation] to learn about Mocks, Stubs and Spies.\n\nThen try to do the following objectives:\n\n- [ ] We want to write a test for the [UserService] which ensures that `\"registerUser persists the user data via UserRepository\"`.\n  Use a Mock for the [UserRepository] since we don't want to test it here (and there is no implantation 😉).\n  Feel free to use a Mock for the [User] object as well, but I'd generally not recommend to mock simple classes as this.\n- [ ] We want to avoid registering users which are already registered.\n  Write another feature method that ensures that `\"registerUser does not persist user data if the user name was registered before\"`.\n  Make your test succeed, ensuring that all others still don't fail.\n  Also, we might want to throw an exception in that case.\n- [ ] ...\n\n\n## Helpful Resources and Further Reading\n\n* [Spock Framework Reference Documentation], especially the [Extensions section] and the [Modules section] not used in this workshop.\n* [Idiomatic Spock] is a presentation by Rob Flechter about some tricks how to write Spock specifications in a better way.\n* [Groovy documentation]\n\n\n[GMavenPlus]: \u003chttps://github.com/groovy/GMavenPlus\u003e\n\n[Groovy]: \u003chttp://www.groovy-lang.org/\u003e\n[Groovy documentation]: \u003chttp://www.groovy-lang.org/documentation.html\u003e\n\n[Spock]: \u003chttp://spockframework.org/\u003e\n[Spock Framework Reference Documentation]: \u003chttp://docs.spockframework.org/\u003e\n[Spock Primer section]: \u003chttp://spockframework.org/spock/docs/2.3/spock_primer.html\u003e\n[Specifications as Documentation section]: \u003chttp://spockframework.org/spock/docs/2.3/spock_primer.html#specs-as-doc\u003e\n[Data Driven Testing section]: \u003chttp://spockframework.org/spock/docs/2.3/data_driven_testing.html\u003e\n[Unrolled Iteration Names]: \u003chttps://spockframework.org/spock/docs/2.3/data_driven_testing.html#_unrolled_iteration_names\u003e\n[Interaction Based Testing section]: \u003chttp://spockframework.org/spock/docs/2.3/interaction_based_testing.html\u003e\n[Extensions section]: \u003chttp://spockframework.org/spock/docs/2.3/extensions.html\u003e\n[Modules section]: \u003chttp://spockframework.org/spock/docs/2.3/modules.html\u003e\n\n[Idiomatic Spock]: \u003chttps://github.com/robfletcher/idiomatic-spock/blob/master/Idiomatic%20Spock.pdf\u003e\n\n[pom.xml]: \u003cpom.xml\u003e\n\n[User]: \u003csrc/main/java/io/github/mkutz/workshop/spocktesting/User.java\u003e\n[UserClassSpec]: \u003csrc/test/groovy/io/github/mkutz/workshop/spocktesting/UserClassSpec.groovy\u003e\n[UserEntity]: \u003csrc/main/java/io/github/mkutz/workshop/spocktesting/UserEntity.java\u003e\n[UserRepository]: \u003csrc/main/java/io/github/mkutz/workshop/spocktesting/UserRepository.java\u003e\n[UserService]: \u003csrc/main/java/io/github/mkutz/workshop/spocktesting/UserService.java\u003e\n[UserServiceClassSpec]: \u003csrc/test/groovy/io/github/mkutz/workshop/spocktesting/UserServiceClassSpec.groovy\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkutz%2Fspock-testing-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkutz%2Fspock-testing-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkutz%2Fspock-testing-workshop/lists"}