完成了单元测试,你的测试之旅才刚上路
作者:网络转载 发布时间:[ 2015/11/26 14:09:50 ] 推荐标签:软件测试 单元测试
注意这里并没有对返回视图这一结果进行测试,因为对于它的测试与controller中的代码将完全相同。
在单元测试中缺少了什么
到目前火上,我们已经成功地实现了对该方法的代码覆盖率,我们也可以选择告一段落了。但是,如果在代码完成单元测试之后停止测试,其结果像是在生产汽车时,在测试过车辆的每一个螺母和螺栓之后直接开始组装汽车一样。很显然,没有人愿意承担如此巨大的风险。在实际生活中,首先要对汽车进行全面的测试驱动,以检查所有参与整体汽车动作的部件,而不仅仅是螺母与螺栓的组装。而在软件开发世界中,我们把这种类似的测试驱动称为集成测试。集成测试是目的是确保各种类之间能够正确地进行协作。
在Java世界中,Spring框架与Java EE平台都可以被视为一种容器,它们为各种可用的服务提供了API,例如使用JDBC进行数据库访问。要确保使用Spring或Java EE进行开发的应用程序能够正常地运行,需要在容器中进行测试,以测试它们与容器中所提供的服务的集成是否能够正常运行。
在以上所举的示例中,还有一部分内容没有测试到,也无法进行测试:
Spring的配置,即通过autowiring方式将所有类进行组装
在model中对PetType的加载,即populatePetTypes()方法
URL是否映射到正确的controller,以及方法标注,即@RequestMapping
在HTTP会话中对Pet实例的设置,即@SessionAttributes("pet")标注
容器内测试
集成测试,以及特定的“容器内测试”正是测试以上提过的这些测试点的解决方案。幸运的是,Spring中提供了一套完整的测试框架,旨在实现这一目的。而Java EE的用户也可以通过使用Arquillian测试框架加入容器内测试的过程中。不过在Java EE的应用程序中存在着不同的类装配方法,例如CDI,而Arquillian中也提供了处理这些差异的方法。有了这些背景知识之后,让我们重新回来看一看这个Pet Clinic示例,并且为上面提过的这些测试点创建测试方法。
Spring中的JUnit集成
正如JUnit的名称所暗示的一样,这是一种用于单元测试的框架。Spring中提供了一种专用的JUnit执行器,它能够在测试开始运行时启动Spring容器。这是在测试类中通过@RunWith标注进行配置的。
@RunWith(SpringJUnit4ClassRunner.class)
public class PetControllerIT { ... }Spring框架也有着自己的配置组件集,可以使用老式的XML文件配置,或选择近流行的Java“配置”类。这里有一种的实践,是使用细粒度的配置组件,因此使用者可以自由选择所需的组件,并按照测试的上下文进行组合。这些配置组件可以通过测试类的@ContextConfiguration标注进行设置。
@ContextConfiguration("classpath:spring/business-config.xml")
public class PetControllerIT { ... }后,Spring框架允许根据某种跨整个应用程序范围的标记,又称为档案,对某些配置选项进行激活(或是关闭)。使用档案的方式相当简单,是在在测试类中设置一个@ActiveProfile标注即可。
@ActiveProfiles("jdbc")
public class PetControllerIT { ... }要使用JUnit测试标准的Spring bean的话,以上的方式已经足够了。但要测试Spring MVC controller的话,你还需要进行更多的工作。
Spring中的测试web上下文
对于web应用程序来说,Spring能够创建一个结构化的上下文,类似于分层架构中的父-子关系。子结点中的内容与web相关,例如controller、格式化器、资源包等等。而父结点中包含了其它部分的内容,例如服务与仓储(repository)等等。为了模仿这种关系,需要在测试类中使用@ContextHierarchy标注,并且对该标注进行配置,让它引用必需的@ContextConfiguration标注:
在下面这个测试片段中,business-config.xml代表了父,而mvc-core-config.xml则代表了子:
@ContextHierarchy({
@ContextConfiguration("classpath:spring/business-config.xml"),
@ContextConfiguration("classpath:spring/mvc-core-config.xml")
})使用者还需要设置@WebAppConfiguration标注,以模仿一个WebApplicationContext的行为,而不是使用更简单的ApplicationContext。
测试controller
在测试中按照以上描述的方法设置好web上下文之后,终于能够开始测试controller了。MockMvc类是实现这一切的入口点,这个类中包含了以下属性:
一个Request生成器,以创建一个Fake的请求
一个Request匹配器,以检查controller的方法执行的结果
一个Result处理器,可以对结果进行任意地操作
MockMvc的实例是通过调用MockMvcBuilders类的静态方法所生成的,其中某个方法生成的实例用于特定的controller集,而另一个方法生成的实例用于整个应用程序的上下文。在后一种情况下,需要提供一个WebApplicationContext的实例以作为参数。实现这一点非常简单,只需在测试类中对该类型的某个属性使用autowire即可。
@RunWith(SpringJUnit4ClassRunner.class)
public class PetControllerIT {
@Autowired
private WebApplicationContext context;
}接下来,通过perform(RequestBuilder)方法执行经过配置的MockMvc实例方法,而RequestBuilder的实例又是通过调用MockMvcRequestBuilders中的静态方法所生成的。其中每一个静态方法都是一种执行特定HTTP方法的途径。
总结一下,使用者可以通过以下代码模仿一个对/owners/1/pets/new路径的GET调用。
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(PetController.class).build();
RequestBuilder getNewPet = MockMvcRequestBuilders.get("/owners/1/pets/new");
mockMvc.perform(getNewPet);后,Spring还通过ResultMatcher接口提供了大量的断言功能,并且提供了MockMvc的fluent API:包括cookie、内容体、底层模型、HTTP状态码,所有这些内容都可以进行检查或实现更多操作。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
iOS单元测试mocha、chai、sinon和istanbul实现百分之百的单元测试覆盖率关于单元测试的总结及思考编写更好的Java单元测试的7个技巧Android单元测试框架Robolectric3.0介绍(一)使用Kiwi单元测试总结单元测试如此重要,为什么你不知道Python单元测试??使用装饰器实现测试跳过和预期故障对Controller的单元测试写好单元测试的10个技巧单元测试的重要性Angular单元测试系列??Component、Directive、Pipe 以及ServiceAndroid单元测试的整理提升单元测试体验的利器--Mockito使用总结iOS UnitTest单元测试Vue的单元测试探索(二)
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南