Workshop for testing Java projects with Spock and Groovy.
In order to get Spock into our Maven project, we need to do the following in our pom.xml.
- Add Groovy and Spock as (test) dependencies (see pom.xml) and (see pom.xml). Note that the version tags can be omitted due to the dependency management (see pom.xml).
- Add ByteBuddy and Objenesis in order to be able to Mock classes (see pom.xml).
- Make Maven aware of
/src/test/groovy
being a test source directory since Maven’s default is/src/test/java
(see pom.xml). - Add the GMavenPlus plugin, to compile your Groovy sources and configure the maven-compiler-plugin (see pom.xml).
- Make Maven Surefire plugin aware of files ending with
*Spec
are test class files since Surefire’s default is*Test
(see pom.xml).
In order to get Spock into our Gradle project, we need to do the following in our [build.gradle].
- Add the Groovy plugin (see build.gradle).
- Add Groovy as a
testImplementation
dependency (see build.gradle). - Add Groovy and Spock dependency (see build.gradle).
- Add ByteBuddy and Objenesis in order to be able to Mock classes (see build.gradle).
- Configure Gradle to use JUnit 5 (see build.gradle)
Read the Spock Primer section of the Spock Framework Reference Documentation to learn about the basic Spock terminology, fixture and feature methods, blocks and expectations.
I 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. Hence, in this workshop we won't use that feature.
Then try to do the following objectives:
- The method
isOfAge
method in User is not implemented properly yet. However, there is a test in UserClassSpec which is annotated with@PendingFeature
.
Use the commented out code inisOfAge
, in order to make the test's expectation be true. Once you did, remove the annotation. - The feature methods uses
given
,when
andthen
. Try to make it shorter using anexpect
block. - Our current implementation of User allows to create users who were not born yet.
Write a
@PendingFeature
that expects that"creating a user with a future birthday throws an IllegalArgumentException"
. - Adjust User to make the feature no longer pending and remove the annotation.
- Write another feature method that specifies that
"no exception in thrown if the birthday is in the past"
.
Read 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.
Then try to do the following objectives:
- 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! Write another feature method to ensure that"isOfAge should return true if the user's birthday is more than 18 years ago"
. Use awhere
block to test several cases. - Use Unrolled Iteration Names to get better test result output.
- Add another data driven test
"isOfAge should return false if the user's birthday is less than 18 years ago"
to test negative cases. - Review your features and try to make more test data driven.
Read the Interaction Based Testing section of the Spock Framework Reference Documentation to learn about Mocks, Stubs and Spies.
Then try to do the following objectives:
- We want to write a test for the UserService which ensures that
"registerUser persists the user data via UserRepository"
. Use a Mock for the UserRepository since we don't want to test it here (and there is no implantation 😉). Feel free to use a Mock for the User object as well, but I'd generally not recommend to mock simple classes as this. - We want to avoid registering users which are already registered.
Write another feature method that ensures that
"registerUser does not persist user data if the user name was registered before"
. Make your test succeed, ensuring that all others still don't fail. Also, we might want to throw an exception in that case. - ...
- Spock Framework Reference Documentation, especially the Extensions section and the Modules section not used in this workshop.
- Idiomatic Spock is a presentation by Rob Flechter about some tricks how to write Spock specifications in a better way.
- Groovy documentation