In my previous post we saw how to test JPA entities along with the Spring Data repository layer in a Spring Boot based application. We made use of JUnit and the AssertJ library.
In this post we will look at how to use the Spock framework to test the same. In fact, in this example, I will be using a combination of Spock based tests along with JUnit tests.To know more about the Spock framework, view the official site here. Spock is a testing and specification framework for Java and Groovy applications.
Let’s get started…
Setup using maven: ( pom.xml)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… | |
<properties> | |
<spock.version>1.1-groovy-2.4</spock.version> | |
</properties> | |
… | |
<dependencies> | |
… | |
<dependency> | |
<groupId>org.spockframework</groupId> | |
<artifactId>spock-spring</artifactId> | |
<scope>test</scope> | |
</dependency> | |
</dependencies> | |
<plugins> | |
… | |
<plugin> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<configuration> | |
<compilerId>groovy-eclipse-compiler</compilerId> | |
<source>1.8</source> | |
<target>1.8</target> | |
</configuration> | |
<dependencies> | |
<dependency> | |
<groupId>org.codehaus.groovy</groupId> | |
<artifactId>groovy-eclipse-compiler</artifactId> | |
<version>2.9.2-01</version> | |
</dependency> | |
<dependency> | |
<groupId>org.codehaus.groovy</groupId> | |
<artifactId>groovy-eclipse-batch</artifactId> | |
<version>2.4.3-01</version> | |
</dependency> | |
</dependencies> | |
</plugin> | |
</plugins> | |
… |
- We need to add the spock-spring dependency. This will bring in the dependencies required to run Spock based tests in a Spring boot based application.
- Notice the use of <spock.version>1.1-groovy-2.4</spock.version>. We are overriding the spock version. Spring Boot 1.5.4 brings in version 1.0 of Spock, however this needs a @ContextConfiguration to run Spock based tests in a Spring Boot application. Overriding the version to 1.1 removes the need to add this annotation.
- In the plugin section , we need to add the dependency for groovy-eclipse-compiler which will compile the groovy code. Spock is based on groovy and hence using Spock to write tests means we write groovy code.
Test classes using Spock
As mentioned in my earlier post, let us consider the same example of 2 JPA entities, SocialMediaSite and Users ( OneToMany). A User has an email which we represented as EmailAddress value object. The test class for this looks as follows:
EmailAddressTest.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.boot.test.db; | |
import com.boot.entity.EmailAddress; | |
import spock.lang.Specification | |
public class EmailAddressTest extends Specification { | |
private static final String testEmail = "test@test.com"; | |
def "throw exception for invalid format of email address"(String emailAddress) | |
{ | |
when: | |
"create invalid email address" | |
def email = new EmailAddress(emailAddress); | |
then: | |
"throw exception for invalid format of email address" | |
def e = thrown(IllegalArgumentException) | |
e.message == "Email Address is Invalid !" | |
where: | |
emailAddress | _ | |
"test@.com" | _ | |
" " | _ | |
null | _ | |
} | |
def "return valid email address"() | |
{ | |
when: | |
"create new email address" | |
def email = new EmailAddress(testEmail); | |
then: | |
"return valid email" | |
email.toString() == testEmail; | |
} | |
} |
- The test class extends spock.lang.Specification. This is how you begin writing a Spock based test.
- Notice the method names are strings, nice descriptive methods names.
- The when/then syntax is for assertions. It’s like saying, “Hey, when this happens then check these things”.
- The where section is the first test method above is data driven.Notice the first 2 columns, emailAddress and a blank. This is because data driven tables in Spock need 2 columns. We need just one. The next rows supply data to the same method.Hence this method is run with all the values mentioned in the first column starting from the 2nd row. Now that is awesome compared to writing multiple methods which do the same thing or if you are using TestNG, this is done using a DataProvider.
- Notice that we have not used any Assertion library here. In Spock this is done using ==.
SocialMediaSiteRepositoryTest.groovy
Notice the @DataJpaTest annotation on the class. It spawns an in-memory data base and runs our tests against it. Along with this, the JPA entities are scanned, Transactions, Hibernate and Spring Data are also configured. There is no need to add @ContextConfiguration as we are using Spock 1.1.
Running Spock tests and JUnit tests together
I have added the 2 groovy test files in src/test/groovy. We can have tests written in JUnit too. I have a JUnit based test class in src/test/java. The groovy eclipse compiler dependency we added in the pom.xml compiles and run tests from both the packages.
Conclusion
This is my first experience with Spock framework and I have thoroughly enjoyed writing tests with it ! There is of course a lot more to the Spock framework. I hope you have enjoyed this quick introduction to Spock for testing Spring Data Repository and JPA entities in a Spring Boot application. The synergy between Spock and the testing changes made in Spring Boot since version 1.4 (test slices) is great !
You can find the project on github.