1. 概述
在这个简短的教程中,我们将展示结合Spring Boot测试框架的支持能力和Spock框架的表现力的好处,无论是单元测试还是集成测试。
2. 项目构建
让我们从一个简单的Web应用程序开始,它可以通过简单的REST调用来打招呼、更改问候语并将其重置为默认值,除了应用程序主类,我们还使用一个简单的RestController来提供以下功能:
@RestController
@RequestMapping("/hello")
public class WebController {
@GetMapping
public String salutation() {
return "Hello world!";
}
}
因此,控制器返回问候语“Hello world!“,@RestController注解和快捷方式注解可确保REST端点注册。
3. 用于Spock和Spring Boot测试的Maven依赖
我们首先添加Maven依赖项,如果需要,还可以添加Maven插件配置。
3.1 使用Spring支持添加Spock框架依赖项
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.2-groovy-2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>1.2-groovy-2.4</version>
<scope>test</scope>
</dependency>
请注意,指定的版本是对使用的groovy版本的引用。
3.2 添加Spring Boot测试
为了使用Spring Boot的测试工具,我们需要以下依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.6.1</version>
<scope>test</scope>
</dependency>
3.3 Groovy
由于Spock基于Groovy,我们还必须添加和配置gmavenplus-plugin插件,以便能够在我们的测试中使用这种语言:
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
请注意,由于我们只需要Groovy进行测试,因此我们将插件goal限制为compileTest。
4. 在Spock测试中加载ApplicationContext
一个简单的测试是检查Spring应用程序上下文中的所有Bean是否都已创建:
@Title("Application Specification")
@Narrative("Specification which beans are expected")
@SpringBootTest
class LoadContextTests extends Specification {
@Autowired(required = false)
private WebController webController
def "when context is loaded then all expected beans are created"() {
expect: "the WebController is created"
webController
}
}
对于这个集成测试,我们需要启动ApplicationContext,而@SpringBootTest提供了这个功能。Spock在我们的测试中使用“when”、“then”或“expect”等关键字提供了部分分隔。
此外,我们可以利用Groovy Truth来检查bean是否为空,作为我们这里测试的最后一行。
5. 在Spock测试中使用WebMvcTest
同样,我们可以测试WebController的行为:
@Title("WebController Specification")
@Narrative("The Specification of the behaviour of the WebController. It can greet a person, change the name and reset it to 'world'")
@SpringBootTest
@AutoConfigureMockMvc
@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
class WebControllerTest extends Specification {
@Autowired
private MockMvc mvc
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(MockMvcResultMatchers.status().isOk()).andReturn().response.contentAsString == "Hello world!"
}
def "when set and delete are performed then the response has status 204 and content changes as expected"() {
given: "a new name"
def NAME = "Emmy"
when: "the name is set"
mvc.perform(MockMvcRequestBuilders.put("/hello").content(NAME)).andExpect(MockMvcResultMatchers.status().isNoContent())
then: "the salutation uses the new name"
mvc.perform(MockMvcRequestBuilders.get("/hello")).andExpect(MockMvcResultMatchers.status().isOk()).andReturn().response.contentAsString == "Hello $NAME!"
when: "the name is deleted"
mvc.perform(MockMvcRequestBuilders.delete("/hello")).andExpect(MockMvcResultMatchers.status().isNoContent())
then: "the salutation uses the default name"
mvc.perform(MockMvcRequestBuilders.get("/hello")).andExpect(MockMvcResultMatchers.status().isOk()).andReturn().response.contentAsString == "Hello world!"
}
}
重要的是要注意,在我们的Spock测试(或者更确切地说是Specifications)中,我们可以使用我们习惯的Spring Boot测试框架中所有熟悉的注解。
6. 总结
在本文中,我们解释了如何设置一个Maven项目以结合使用Spock和Spring Boot测试框架。此外,我们已经看到这两个框架如何完美地相互补充。
如需更深入的了解,请查看我们关于使用Spring Boot进行测试、Spock框架和Groovy语言的教程。
与往常一样,本教程的完整源代码可在GitHub上获得。