@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TodoControllerTest {
@Autowired
TodoController controller;
@Autowired
TodoService todoService;
MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
@Configuration
static class Config {
@Bean
public TodoController getTodoController() {
return new TodoController();
@Bean
public TodoService getTodoService() {
return new TodoService();
@Test
public void testFindAll() throws Exception {
mockMvc.perform(get("/")).andExpect(view().name("todo/list"));
上面的例子是一个非常简单的测试——但还是有很多“样板”代码要写,有很多事情要做。在这个例子中,我们使用一个内部的Configuration类为Spring配置了一个控制器和它的服务,然后使用MockMvc函数向处理程序发送请求。然后,我们使用MockMvc函数向处理者方法发送请求(使用perform),并使用andExpect验证返回的视图名称。
上面的测试有什么问题吗?其实没什么——但想象一下一个更复杂的控制器方法,有多个处理方法,接受更多的参数并产生更多的输出。编写测试会花费更多的时间,特别是如果良好的测试覆盖率很重要的话。此外,大多数真实的测试需要更多的配置(XML或类配置、会话和环境、安全等)。
使用Parasoft Jtest生成Spring测试
Parasoft Jtest的单元测试助手可以帮助开发人员以多种方式编写Spring测试:
自动快速生成Spring MVC测试的模板代码
自动生成参数化测试,提高测试覆盖率
模拟依赖关系,以隔离辅助方法并简化测试
在运行时收集覆盖率数据并分析测试流程
为改进测试提供建议,并提供快速修补办法
自动生成测试
在Parasoft Jtest中生成Spring测试是很直接的——只需在你的IDE中为你的控制器选择一个Spring处理方法,并选择一个测试创建动作:
选择Regular Spring或Parameterized Spring会自动为你生成模板化的Spring MVC测试,包括Configuration类(以及你的控制器所依赖的所有Bean)。mockMvc.perform调用也被添加进来,并被预先配置为调用创建测试的处理方法。Jtest 单元测试助手甚至增加了一些例子断言,你可以取消注释和配置。
Parasoft Jtest支持使用XML或类配置生成测试,通过在偏好设置中设置 "ContextConfiguration attributes for Spring tests "选项。
模拟依赖性
在单元测试中管理依赖关系是至关重要的,因为大部分的复杂性和工作来自于隔离被测单元。Jtest单元测试助手默认使用Mockito或PowerMockito来模拟依赖关系(如果你不希望这样,可以在偏好设置中禁用)。模拟依赖关系允许测试控制这些依赖关系,将处理程序方法与应用程序的其他部分隔离开来,以便将测试工作集中在处理程序上。在我们的示例处理程序中,findAll方法是在TodoService上被调用的——如果我们使用一个真正的TodoService,我们就有效地测试了TodoController和TodoService。这可能是我们在集成测试中想要的,但不是在单元测试中想要的。在测试中模拟TodoService.findAll的响应,可以让我们把测试工作集中在处理方法上。
(如果你想了解更多关于在Spring测试中模拟依赖关系的信息,请阅读我的下一篇文章。)
Spring Boot
由于Spring Boot为Bean提供了简化的配置,以及额外的测试注释,所以当单元测试助理在你的项目中检测到Spring Boot时,会生成略有不同的测试。例如,MockMvc是自动连接的,依赖关系使用@MockBean进行模拟,并使用@SpringBootTest注解。
运行测试和分析结果
你可以使用任何普通的JUnit运行器运行生成的测试。Parasoft Jtest提供了运行JUnit和分析测试的工具栏操作。
测试运行后,会显示测试执行流程,单元测试助手会提出改进测试的建议,并在IDE中报告:
提供处理程序方法输入
处理程序方法通常被配置为接受路径、查询或其他参数作为方法的参数。要测试MVC处理程序方法,可以使用MockMvc来构建路径/查询和调用该方法所需的任何其他参数。
Jtest单元测试助理会自动配置mockMvc.perform调用来调用处理程序方法。单个参数在测试中显示为局部变量(或参数化测试中的参数),需要配置这些参数才能使测试正确运行。
例如(下文单元测试助手缩写为UTA):
@Test public void testGetPerson() throws Throwable {
这里,需要配置 "id"字符串——如果没有,那么使用的路径将是"/people/",Spring将不会把提供的路径匹配到合适的处理方法。
class="p1″>单元测试助手会寻找各种类型的处理程序方法参数,并通过以下方式自动为它们准备测试:
HttpSession(增加一个setAttribute()调用的例子)
头部(增加一个header()调用)
请求主体(添加一个payload变量和content()调用)
认证(在setup方法中添加了一个实例,以及一个principal()调用)
运行一个不会导致处理程序方法被调用的测试,会产生类似下面的建议:
验证处理程序方法的输出
根据处理程序方法要提供给调用者的内容,它可能返回多种类型。大多数情况下,处理方法会返回一个ModelAndView(或类似的对象,如Model或RedirectView)来为页面提供服务,或者返回某种类型的ResponseEntity(有时只是要序列化的原始对象)。这个响应可以访问Spring MVC测试框架进行验证。
例如,Jtest单元测试助理为一个返回ModelAndView的处理方法添加了以下断言:
// When
String id = "1"
ResultActions actions = mockMvc.perform(get("/people/" + id))
// Then
// actions.andExpect(status().isOk())
// actions.andExpect(header().string("", ""))
// actions.andExpect(view().name(""))
// actions.andExpect(model().attribute("", ""))
一旦测试生成,你就可以取消对这些断言的注释并填充值,以快速建立一个有用的和有价值的测试。如果一个断言在运行时失败了,单元测试助手提供了一个建议和快速修复,以自动更新预期值或简单地删除断言。为了快速设置一个正确的断言值,你可以取消对断言的注释,让它失败,然后使用快速修复来设置正确的期望值。
Spring(结合Spring Boot)是领先的企业级Java应用框架,因此需要适当的测试水平,以确保用它构建的应用的质量和安全性。但遗憾的是,这种水平的测试目前还没有实现,主要是由于缺乏时间和需要大量的人工编码和维护。Parasoft Jtest 单元测试助手不仅提供了单元测试自动化,还提供了指导性的测试创建和依赖性管理,以加速测试创建和减少维护。
要了解更多信息,请阅读单元测试助手如何利用模拟框架帮助进行依赖性管理。