这个迷你系列的第一个博客介绍了Spring MVC测试框架,并展示了其在单元测试Spring MVC Controller类中作为控制器而不是POJO进行单元测试的用途。 现在是时候讨论使用框架进行集成测试了。

“集成测试”是指将Spring上下文加载到测试环境中,以便控制器可以在“端到端”测试中与合作者一起工作。

同样,我将从Spring Social Facebook项目中为FacebookPostsController编写一个测试,并且正如您所期望的那样,该测试将是我的FacebookPostsControllerTest类的集成测试版本。 如果需要查看FacebookPostsController代码或原始的FacebookPostsControllerTest代码,请查看我的上一个博客 。 有关FacebookPostsController代码的完整介绍,请参见Spring Social Facebook博客 。

创建集成测试的第一步是将Spring上下文加载到测试环境中。 这是通过在FacebookPostsControllerTest类中添加以下注释来完成的:

  1. @RunWith ( SpringJUnit4ClassRunner.class )
  2. @WebAppConfiguration
  3. @ContextConfiguration(“文件名”)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({ "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml", "file:src/main/webapp/WEB-INF/spring/data.xml" })
public class FacebookPostsControllerTest {

@RunWith ( SpringJUnit4ClassRunner.class )或@ContextConfiguration(“ file-names”)并没有什么新意,因为它们从Spring 2.5开始就出现了,如果您是Spring开发人员,那么您之前可能已经在集成测试中使用过它们。 新人是@WebAppConfiguration 。

这些批注协同工作以配置您的测试环境。 @RunWith告诉JUnit使用Spring JUnit类运行器运行测试。 @WebAppConfiguration告诉SpringJUnit4ClassRunner集成测试要加载的ApplicationContext应该是WebApplicationContext ,而@ContextConfiguration用于指定加载哪个XML文件以及从何处加载。

在这种情况下,我正在加载项目的“ servlet-context.xml”和“ data.xml”文件。 “ servlet-context.xml”文件包含Spring Web应用程序所需的所有标准位,例如<annotation-driven />和视图解析器,而“ data.xml”则包含该应用程序的Spring Social组件。 这里要注意的一点是,我故意使用
我想运行端到端集成测试来访问文件系统,数据库等的伪生产配置文件。

这只是示例代码,在集成测试中通常不会涉及生产数据库或其他相关资源。 通常,您将配置您的应用程序以访问集成测试数据库和其他资源。 解决此问题的一种方法是创建一个测试 XML配置文件。 但是,不要像我在一个项目中看到的那样,为项目中的每个Maven模块创建单独的测试 XML文件。 原因是当您对代码进行更改时,最终要更改一大堆配置文件才能使集成测试再次正常工作,这既无聊又耗时。 更好的方法是拥有一个版本的XML配置,并使用Spring配置文件为不同的环境配置应用程序。 如果确实选择使用配置文件,则还需要将@ActiveProfiles(“profile-name”)批注添加到上面列出的其他三个批注中。 但是,这超出了本博客的范围。

假设您使用的是自动装配,并且您已经正确设置了<context:component-scan /> ,那么下一步就是将以下实例变量添加到测试类中:

@Autowired private WebApplicationContext wac;

这告诉Spring将先前创建的WebApplicationContext注入到测试中。 然后,可以在非常简单的一行setup()方法中使用它:

@Before public void setUp() throws Exception { mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); }

类似于此测试的“独立” /“编程”版本, setup()方法的目的是创建一个mockMvc实例,然后使用它来执行测试。 此处的区别在于,它只是通过使用WebApplicationContext作为MockMvcBuilders的参数来MockMvcBuilders

整理好setup()方法后,接下来要做的是编写一个测试,我将从上一个博客中重写testShowPostsForUser_user_is_not_signed_in()作为集成测试。 令人惊讶的是,该代码比以前的JUnit版本更简单:

@Test public void testShowPostsForUser_user_is_not_signed_in() throws Exception { ResultActions resultActions = mockMvc.perform(get("/posts").accept(MediaType.ALL)); resultActions.andExpect(status().isOk()); resultActions.andExpect(view().name("signin")); }

如果将此代码与我以前的博客中的testShowPostsForUser_user_is_not_signed_in()代码进行比较,您会发现它几乎相同。 唯一的区别是无需设置任何模拟对象。

在这一点上,我将演示testShowPostsForUser_user_is_signed_in测试的集成测试版本,但这确实有些棘手。 原因是要掌握他们的Facebook帖子列表,用户必须登录其Facebook帐户,这意味着在正确的必要HttpServletRequest对象之前,需要对服务器进行多次顺序调用状态以方便致电Facebook检索帖子列表。 对于示例代码来说,这似乎有点太复杂了,这是我不想在
真实的项目。

我不是将这种复杂性视为Spring MVC测试框架的局限性,而是要强调最佳实践,这是确保对服务器的调用尽可能独立且原子。

当然,我可以使用模拟对象或创建虚拟Facebook服务,但是,这超出了本博客的范围。

一个独立的一个很好的例子,原子服务器调用是REST调用testConfirmPurchases_selection_1_returns_a_hat(...)用于测试的OrderController从我采取类的Spring MVC,Ajax和JSON第2部分-服务器端代码博客。 此代码在Ajax博客中进行了全面描述,它请求购买确认,并以JSON的形式返回。

下面OrderController了返回JSON的OrderController代码:

/** * Create an order form for user confirmation */ @RequestMapping(value = "/confirm", method = RequestMethod.POST) public @ResponseBody OrderForm confirmPurchases(@ModelAttribute("userSelections") UserSelections userSelections) { logger.debug("Confirming purchases..."); OrderForm orderForm = createOrderForm(userSelections.getSelection()); return orderForm; } private OrderForm createOrderForm(List<String> selections) { List<Item> items = findItemsInCatalogue(selections); String purchaseId = getPurchaseId(); OrderForm orderForm = new OrderForm(items, purchaseId); return orderForm; } private List<Item> findItemsInCatalogue(List<String> selections) { List<Item> items = new ArrayList<Item>(); for (String selection : selections) { Item item = catalogue.findItem(Integer.valueOf(selection)); items.add(item); } return items; } private String getPurchaseId() { return UUID.randomUUID().toString(); }

尽管它返回的JSON看起来像这样:

{"items":[{"id":1,"description":"description","name":"name","price":1.00}, {"id":2,"description":"description2","name":"name2","price":2.00}],"purchaseId":"aabf118e-abe9-4b59-88d2-0b897796c8c0"}

下面以冗长的样式显示了测试testConfirmPurchases_selection_1_returns_a_hat(...)的代码。

@Test public void testConfirmPurchases_selection_1_returns_a_hat() throws Exception { final String mediaType = "application/json;charset=UTF-8"; MockHttpServletRequestBuilder postRequest = post("/confirm"); postRequest = postRequest.param("selection", "1"); ResultActions resultActions = mockMvc.perform(postRequest); resultActions.andDo(print()); resultActions.andExpect(content().contentType(mediaType)); resultActions.andExpect(status().isOk()); // See http://goessner.net/articles/JsonPath/ for more on JSONPath ResultMatcher pathMatcher = jsonPath("$items[0].description").value("A nice hat"); resultActions.andExpect(pathMatcher); }

上面的代码不是Spring Guys希望您编写的代码; 但是,以冗长的格式更容易讨论正在发生的事情。 该方法的结构类似于第1部分中讨论的testShowPostsForUser_user_is_signed_in(...)方法。第一步是使用静态MockMvcRequestBuilders.post(...)方法创建MockHttpServletRequestBuilder类型的postRequest对象。 值"1""selection"参数将添加到结果对象中。

然后将postRequest传递给mockMvc.perform(...)方法,并返回一个ResultActions对象。

然后使用andExpect(...)方法验证ResultActions对象,以检查HTTP状态(ok = 200)和内容类型为"application/json;charset=UTF-8"

此外,我还添加了一个andDo(print())方法调用,以显示HttpServletRequestHttpServletResponse对象的状态。 该调用的输出如下所示:

MockHttpServletRequest:HTTP Method = POSTRequest URI = /confirmParameters = {selection=[1]}Headers = {}Handler:Type = com.captaindebug.store.OrderControllerMethod = public com.captaindebug.store.beans.OrderForm com.captaindebug.store.OrderController.confirmPurchases(com.captaindebug.store.beans.UserSelections)Resolved Exception:Type = nullModelAndView:View name = nullView = nullModel = nullFlashMap:MockHttpServletResponse:Status = 200Error message = nullHeaders = {Content-Type=[application/json;charset=UTF-8]}Content type = application/json;charset=UTF-8Body = {"items":[{"id":1,"description":"A nice hat","name":"Hat","price":12.34}],"purchaseId":"d1d0eba6-51fa-415f-ac4e-8fa2eaeaaba9"}Forwarded URL = nullRedirected URL = nullCookies = []

最后一项测试使用静态MockMvcResultMatchers.jsonPath(...)检查"$items[0].description"的JSON路径的值是否为"A nice hat" 。 为了使用jsonPath(...)静态方法,您必须在POM.xml中包含JSON Path模块以解析JSON。

<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>0.8.1</version><scope>test</scope></dependency>

JSonPath是一种从JSon数据中选择性提取字段的方法。 它基于XML的XPath思想。

显然,我上面用过的冗长风格不需要编写测试。 下面的代码显示与Spring的Guy设计的相同代码:

@Test public void testConfirmPurchases_spring_style() throws Exception { mockMvc.perform(post("/confirm").param("selection", "1")).andDo(print()) .andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(status().isOk()) .andExpect(jsonPath("$items[0].description").value("A nice hat")); }

所以,仅此而已。 概括地说,我们的想法是向您的单元测试中添加适当的注释,以便Spring加载您的XML配置以创建WebApplicationContext 。 然后将其注入到您的测试中,并在创建mockMvc时作为参数传递给Spring MVC Test框架。 然后编写测试,其想法是将适当构造的MockMvcRequestBuilders对象传递给mockMvc.perform(...)方法,然后将其返回值声明为通过或失败测试。

该博客的代码可在GitHub上找到: https : //github.com/roghughe/captaindebug/在Facebook和Ajax-JSON项目中。

参考: Spring的MVC测试框架入门–第2部分,来自我们的JCG合作伙伴 Roger Hughes,来自Captain Debug的Blog博客。

翻译自: https://www.javacodegeeks.com/2013/07/getting-started-with-springs-mvc-test-framework-part-2.html

Spring MVC测试框架入门–第2部分相关推荐

  1. Spring MVC测试框架入门–第1部分

    最新推出的主要Spring框架是Spring MVC测试框架,Spring Guys声称它是"一流的JUnit支持,可通过流畅的API测试客户端和服务器端Spring MVC代码" ...

  2. spring框架mvc框架_Spring的MVC测试框架入门–第1部分

    spring框架mvc框架 最新推出的主要Spring框架是Spring MVC测试框架,Spring Guys声称它是"一流的JUnit支持,可通过流畅的API测试客户端和服务器端Spri ...

  3. spring框架mvc框架_Spring MVC测试框架入门–第2部分

    spring框架mvc框架 这个迷你系列的第一个博客介绍了Spring MVC测试框架,并演示了其在单元测试Spring MVC Controller类中作为控制器而不是POJO进行单元测试的用途. ...

  4. Spring MVC测试框架

    原文链接:http://jinnianshilongnian.iteye.com/blog/2004660 Spring MVC测试框架详解--服务端测试 博客分类: springmvc杂谈 spri ...

  5. 14.6 Spring MVC 测试框架(翻译)

    14.6 Spring MVC 测试框架(每天翻译一点点) Spring MVC测试框架对 Spring MVC 代码提供一流的测试支持 ,它拥有一个 fluent API ,可以和JUnit, Te ...

  6. Spring MVC测试框架详解——服务端测试

    随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的.从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用sp ...

  7. spring mvc + mybatis 框架搭建 ( idea + gradle)

    spring mvc + mybatis 框架搭建 idea + gradle 刚刚入门,只是个人见解,如有错误或者问题欢迎指出指正. 邮箱: [ wgh0807@qq.com ] 文章引用: [ap ...

  8. Spring MVC 4快速入门Maven原型已改进

    Spring Boot使Spring入门非常容易. 但是仍然有人对不使用Spring Boot并以更经典的方式引导应用程序感兴趣. 几年前,我创建了一个原型(早于Spring Boot),简化了引导S ...

  9. Spring MVC的框架组件

    Spring MVC的框架组件 DispatcherServlet:前端控制器 用户请求到达前端控制器,它相当于MVC中的C,dispatcherServlet没有处理业务的能力,它是整个流程的控制中 ...

最新文章

  1. hive的用户和用户权限
  2. 在c语言中除法运算符,c – 不需要的除法运算符行为,我该怎么办?
  3. Hologres如何基于roaringbitmap实现超高基数UV计算?
  4. php ci post 请求,CI框架中判断post,ajax,get请求的方法
  5. Linux学习笔记-Linux下读写文件
  6. 如何感性地理解EM算法?
  7. presentViewController:navigationController animated:YES completion:^(void)
  8. springboot 配置全局响应数据_spring boot 全局事务配置
  9. 一个c3p0的数据库连接池的多线程测试
  10. linq group by 多个字段取值以及取出重复的数据
  11. 《Java基础入门》笔记——01 Java初步
  12. win10 两台电脑之间共享桌面及共享文件(手把手教学)
  13. 【分享360域名批量查询工具】
  14. 马斯洛提出动机理论_动机理论:工作背后的动力机制
  15. thinkphp5 关联预载入怎么用
  16. JAVA程序设计实战(1-9章)
  17. Linux故障处理——磁盘空间满缺找不到对应大文件
  18. 西部学刊杂志西部学刊杂志社西部学刊编辑部2022年第14期目录
  19. 2022-2027年中国三相功率因数表行业市场深度分析及投资战略规划报告
  20. Windows10要成为“史上最安全的操作系统”,还需要你对它做了这几件事

热门文章

  1. 工程打包是什么意思_太生动形象了!500个建筑施工3D动画演示,施工工艺一目了然,零基础工程人也能看懂...
  2. java aqs详解_Java AQS底层原理解析
  3. redis存opc_KEPServerEX6完整免费版
  4. hibernate在saveOrUpdate时,update报错:a different object with the same identifier value was already assoc
  5. java 轻量级文件数据库_Java:如何创建轻量级数据库微服务
  6. java求期望_Java 11的期望
  7. java message_Java Message System简介
  8. java字符连接字符串数组_Java中连接字符串的最佳方法
  9. 如何在CircleCI上构建支持Graal的JDK8?
  10. java中属性外部化_用Java可外部化