How to Build a Food...
December 18, 2024
We’ll look at Spock, a Groovy testing framework. Mainly, Spock aims to be a more powerful alternative to the traditional JUnit stack, by leveraging Groovy features.
By making use of Groovy, Spock introduces new and expressive ways of testing our Java applications, which simply aren’t possible in ordinary Java code. We’ll explore some of Spock’s high-level concepts during this article, with some practical step-by-step examples.
You have some knowledge about spring-boot and testing concept like mocking, Stubbing, etc.
Here we learn the Spock framework with the Spring boot application.
To use Spock in spring boot, add the below dependency into pom.xml
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>2.3-groovy-4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>4.0.4</version>
</dependency>
And add a plugin for groovy support
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
Make groovy class and extend the specification to it (spock.lang.specification).
For testing we made one simple method.
@SpringBootTest
class Test1 extends Specification {
def "Simple Test"(){
expect:
1+1 == 2
}
}
Here “def” keyword is used to define method after this you can add method discerption.
Now run the test
Output:
You see Test Case Passed successfully.
First, create a ‘Hello’ controller
@RestController
public class Hello {
@GetMapping("/hello")
public String greeting (){
return "Hello World! ";
}
Now for this controller, we are writing test cases using Spock.
class HelloTest extends Specification {
@MockBean
def cont = new Hello ()
MockMvc mvc = MockMvcBuilders.standaloneSetup(cont). build()
def "when get is performed then the response has status 200 and content is 'Hello world!'"() {
expect: "Status is 200 and the response is 'Hello world!'"
mvc.perform(MockMvcRequestBuilders.get("/hello"))
.andExpect(status().isOk())
.andReturn()
.response
.contentAsString == "Hello World! "
}
}
Output:
1) All the blocks in a Spock based spec are optional. However, if present “when” and “then” should appear together in sequence.
2) If you just need to validate an assertion (and you don’t have a need of when block), you can use “expect” block. It can be used to assert pre-conditions even before when and then blocks (and can be used multiple times in a test).
Here We Have 4 Methods used to define global or redundant code.
/**
* Call only one time for all test cases
* You can define a spec for static or whole test cases that have the same value
* */
def setupSpec() {
}
/**
* Call only once at the end of all test cases
* */
def cleanupSpec() {
}
/**
* Call for every test case
* It calls for every time before the test case
* */
def setup () {
}
/**
* Call for every test case
* It calls for every time after test case
* */
def cleanup() {
}
Using Spock, you can generate reports too
For that, we must add 3 dependencies into pom.xml
<dependency>
<groupId>com.athaydes</groupId>
<artifactId>spock-reports</artifactId>
<version>2.3.0-groovy-3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.6</version>
<scope>test</scope>
</dependency>
After that reload the maven file and run all the test cases
Then build -> spock-reports -> index.html you can find reports for test cases you run.
(For Reference you see the below image.)
Below Screenshot Showing Index.html
For mocking you must use the Mock () method
Ex: – def studentDatabase = Mock (StudentDatabase.class)
With Mocks, you don’t have to do a lot of setups, but you can validate the interactions that happened with the mock objects supplied to the application under test.
With mocks, you can do things like
For a mock example refer to the GitHub link.
Link = Spock Demo Document
Stubbing is nothing but setting up pre-defined or canned responses on the Mock invocations to test the different flows/scenarios of the application under test.
A Stub is like a Mock which in a way emulates the behaviour of the real object. You can simply call it a programmed Mock.
Syntax:
StubbedObject.StubbedMethod(argument list) >> “Stubbed Response”
Here we are using @WebMvcTest annotation and @MockMvc for calling the rest API.
In a later version of 3.0 spring boot, you must mention your main runner class (@springbootapplication annotation class) into @ContextConfiguration (see below stubbing example)
Here in the example, we use @SpringBean for adding bean.
Registers mock/stub/spy as a spring bean in the test context.
You also need to directly assign the Mock/Stub/Spy to the field using the standard Spock syntax. You can even use the initializer blocks to define common behaviour however, they are only picked up once they are attached to the Specification.
@SpringBean definitions can replace existing Beans in your ApplicationContext.
To run the below example, we must add one more dependency
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>2.3-groovy-4.0</version>
</dependency>
@ContextConfiguration (classes = Demo1Application)
@WebMvcTest
class HelloTest extends Specification {
@Autowired
protected MockMvc mvc
@SpringBean
HelloService helloService = Stub() {
greeting () >> "Stubbed data"
}
def "when get is performed then the response has status 200
and service method calls"() {
when: "Calls Method"
def result =
mvc.perform(MockMvcRequestBuilders.get("/greeting"))
then: "check value"
result.andExpect(status().isOk())
and: "check for stubbed string"
result.andReturn().response
.contentAsString == "Stubbed data"
}
in this blog, we created test cases for the controller. the same way you create test cases for service or any class. If you prefer readable test cases, then I’m recommended you use the Spock framework for writing test cases.
To see the complete demo, use the GitHub link (Spock Demo Document).