如何使用Java单元测试助手高效构建和改进Spring测试?

SWTOR 2021-01-21 16:03:10
java 测试 使用 单元测试 单元


Spring框架(连同Spring Boot一起)是最流行的Java企业软件框架之一。它在关键任务应用中的使用意味着它的质量和安全性受到了严格的审查。

此前,我们讨论了开发人员如何不喜欢单元测试,尽管它的改进记录已被证实,并详细介绍了Parasoft Jtest的单元测试助手如何提供一种指导性和自动化的测试方法,使测试不仅更容易接受,而且更容易和更有效。在这篇文章中,我将继续以Spring框架为主题,向你展示如何在这个重要的应用框架中利用自动化和引导式测试。

测试Spring应用的挑战

Spring框架为集成测试提供了不错的支持,但要正确设置测试用例,需要大量的手工编码。构建和维护Spring应用的测试给开发人员带来了一系列独特的挑战,包括以下几点

  • 必须对Spring框架进行初始化和配置
  • 应用程序通常有第三方库的依赖性(持久存储、外部服务等)
  • 应用程序通常使用内置的Spring功能,用于会话、安全、消息传递等。对于刚接触Spring测试的开发人员来说,这些功能的设置可能会很棘手
  • 需要适当配置应用程序的依赖关系(即Bean

这些挑战,再加上编写全面的可维护的测试套件一般需要花费大量的时间,导致开发人员没有编写足够的测试,反过来,这又会导致安全漏洞、缺陷、回归和许多令人头痛的问题。

Parasoft Jtest Unit Test Assistant可以帮助你,它使生成、改进和维护JUnit测试的过程变得更加简单和省时,这样开发人员就可以快速构建好的测试,并回到他们更加偏好的事情上——编写代码。

Spring MVC测试框架

Spring框架包括一个测试框架,它使控制器、服务和其他组件的测试变得更加容易。它包括配置Spring测试容器、调用Controller处理方法和使用自定义断言验证行为的功能。

一个Spring MVC控制器的例子

@Controller
public class TodoController { @Autowired
private TodoService service;
@GetMapping("/") public String findAll(Model model) {
List<Todo> todos = service.findAll();
model.addAttribute("todos", todos);
return "todo/list";
}
}

这个示例中,控制器实现了一个简单的REST服务,以从 "待办事项 "列表中获取项目。它依赖于一个TodoService,其中包含业务逻辑。

为了测试findAll方法,我们需要一个JUnit测试,它可以完成以下工作

  • Spring容器中配置被测试的ControllerTodoController所依赖的TodoService
  • findAll处理方法发送一个有效的请求。
  • 验证响应的元素,包括返回值("todo/list")和Model属性 "todos"

一个Spring MVC Junit测试的例子可能是这样的

@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测试

  1. 自动快速生成Spring MVC测试的模板代码
  2. 自动生成参数化测试,提高测试覆盖率
  3. 模拟依赖关系,以隔离辅助方法并简化测试
  4. 在运行时收集覆盖率数据并分析测试流程
  5. 为改进测试提供建议,并提供快速修补办法

自动生成测试

Parasoft Jtest中生成Spring测试是很直接的——只需在你的IDE中为你的控制器选择一个Spring处理方法,并选择一个测试创建动作

选择Regular SpringParameterized Spring会自动为你生成模板化的Spring MVC测试,包括Configuration类(以及你的控制器所依赖的所有Bean)。mockMvc.perform调用也被添加进来,并被预先配置为调用创建测试的处理方法。Jtest 单元测试助手甚至增加了一些例子断言,你可以取消注释和配置。

Parasoft Jtest支持使用XML或类配置生成测试,通过在偏好设置中设置 "ContextConfiguration attributes for Spring tests "选项。

模拟依赖性

在单元测试中管理依赖关系是至关重要的,因为大部分的复杂性和工作来自于隔离被测单元。Jtest单元测试助手默认使用MockitoPowerMockito来模拟依赖关系(如果你不希望这样,可以在偏好设置中禁用)。模拟依赖关系允许测试控制这些依赖关系,将处理程序方法与应用程序的其他部分隔离开来,以便将测试工作集中在处理程序上。在我们的示例处理程序中,findAll方法是在TodoService上被调用的——如果我们使用一个真正的TodoService,我们就有效地测试了TodoControllerTodoService。这可能是我们在集成测试中想要的,但不是在单元测试中想要的。在测试中模拟TodoService.findAll的响应,可以让我们把测试工作集中在处理方法上。

如果你想了解更多关于在Spring测试中模拟依赖关系的信息,请阅读我的下一篇文章1.21。)

Spring Boot

由于Spring BootBean提供了简化的配置,以及额外的测试注释,所以当单元测试助理在的项目中检测到Spring Boot时,会生成略有不同的测试。例如,MockMvc是自动连接的,依赖关系使用@MockBean进行模拟,并使用@SpringBootTest注解。

运行测试和分析结果

你可以使用任何普通的JUnit运行器运行生成的测试。Parasoft Jtest提供了运行JUnit和分析测试的工具栏操作。

测试运行后,会显示测试执行流程,单元测试助手会提出改进测试的建议,并在IDE中报告

提供处理程序方法输入

处理程序方法通常被配置为接受路径、查询或其他参数作为方法的参数。要测试MVC处理程序方法,可以使用MockMvc来构建路径/查询和调用该方法所需的任何其他参数。

Jtest单元测试助理会自动配置mockMvc.perform调用来调用处理程序方法。单个参数在测试中显示为局部变量(或参数化测试中的参数),需要配置这些参数才能使测试正确运行。

例如(下文单元测试助手缩写为UTA

@Test public void testGetPerson() throws Throwable { // When String id = ""; // UTA: Configure an appropriate parameter value since the tested method depends on it ResultActions actions = mockMvc.perform(get("/people/" + id));

这里,需要配置 "id"字符串——如果没有,那么使用的路径将是"/people/"Spring将不会把提供的路径匹配到合适的处理方法。

class="p1>单元测试助手会寻找各种类型的处理程序方法参数,并通过以下方式自动为它们准备测试

  • HttpSession(增加一个setAttribute()调用的例子)
  • 头部(增加一个header()调用)
  • 请求主体(添加一个payload变量和content()调用)
  • 认证(在setup方法中添加了一个实例,以及一个principal()调用)

运行一个不会导致处理程序方法被调用的测试,会产生类似下面的建议:

验证处理程序方法的输出

根据处理程序方法要提供给调用者的内容,它可能返回多种类型。大多数情况下,处理方法会返回一个ModelAndView(或类似的对象,如ModelRedirectView)来为页面提供服务,或者返回某种类型的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 单元测试助手不仅提供了单元测试自动化,还提供了指导性的测试创建和依赖性管理,以加速测试创建和减少维护。

要了解更多信息,请阅读单元测试助手如何利用模拟框架帮助进行依赖性管理1.21。

版权声明
本文为[SWTOR]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/dhorde/p/14308486.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云