基于Spring-WS的Restful API的集成测试

在很多Java企业级应用中,Spring占据了非常重要的位置,这就导致了基本上的技术选型都是围绕着Spring来, 比方说笔者最近的项目需要开发一个Restful的API接口,选型的时候就说,客户架构师直接就拍了spring-ws,原因呢?系统中其他的模块都是用的Spring-ws,保持一致,而且社区活跃,文档丰富,遇到问题易解决。好了,入正题。

既然选定了Spring-WS, 已经TDD入魔的我,首先想到的就是我应该怎么测试这个API接口呢? 作为业界最成熟的框架,Spring为测试其Web应用提供了非常好用的辅助类MockMvc。

首先,在项目的测试代码中加入辅助Spring Web测试的库
Gradle代码   收藏代码
  1. testCompile(  
  2.             "org.springframework:spring-test:$springVersion",  
  3.             "org.springframework.ws:spring-ws-test:2.1.0.RELEASE",  
  4.             "javax.servlet:javax.servlet-api:3.0.1",  
  5.             "com.jayway.jsonpath:json-path-assert:0.9.0"  
  6.     )  
其中,jsonpath库的依赖是为了更好的做json格式数据的断言。

然后,编写测试代码
Java代码   收藏代码
  1. //指定使用SpringIntegration测试,并且制定了运行测试的ApplicationContext  
  2. @RunWith(SpringJUnit4ClassRunner.class)  
  3. @ContextConfiguration(locations = {"classpath:spring-servlet.xml"})  
  4. public class ApiControllerIntegrationTest {  
  5.   
  6.     @Autowired  
  7.     private ApiController controller;  
  8.   
  9.     private MockMvc mockMvc;  
  10.   
  11.     @Before  
  12.     public void setUp() throws Exception {  
  13.         //绑定需要测试的Controller到MockMvcshang  
  14.         mockMvc = MockMvcBuilders.standaloneSetup(controller).build();  
  15.     }  
  16.   
  17.     @Test  
  18.     public void testGet() throws Exception {  
  19.         //发出请求,在请求中可以设置一个http request可设置的所有参数  
  20.         mockMvc.perform(get("/requests/1")  
  21.                 .contentType(MediaType.APPLICATION_JSON)  
  22.                 .accept(MediaType.APPLICATION_JSON)  
  23.                 .param("userId""xianlinbox")  
  24.         )  
  25.         //验证Respondse,status()中,可验证所有的HTTP Status CODE  
  26.         //另外,使用了jsonPath更优雅的做json属性值的验证  
  27.                 .andExpect(status().isOk())  
  28.                 .andExpect(jsonPath("$.userId").value("xianlinbox"))  
  29.                 .andExpect(jsonPath("$.requestId").value("1"))  
  30.                 .andExpect(jsonPath("$.requestType").value("GET"));  
  31.     }  
  32.   
  33.     @Test  
  34.     public void testPost() throws Exception {  
  35.         mockMvc.perform(post("/requests")  
  36.                 .contentType(MediaType.APPLICATION_JSON)  
  37.                 .accept(MediaType.APPLICATION_JSON)  
  38.                 .content("this is the message")  
  39.                 .param("userId""xianlinbox")  
  40.         )  
  41.                 //使用print()可打印出当前测试设计的HTTP Request/Responsed的所有信息,方便定位问题  
  42.                 //Post方法的返回结果应该是202(HttpStatus.Created),对象创建成功  
  43.                 .andDo(print())  
  44.                 .andExpect(status().isCreated())  
  45.                 .andExpect(jsonPath("$.userId").value("xianlinbox"))  
  46.                 .andExpect(jsonPath("$.requestType").value("POST"))  
  47.                 .andExpect(jsonPath("$.message").value("this is the message"));  
  48.     }  
  49.   
  50. }  

testPost方法中的print()语句打印出的效果如下:
MockHttpServletRequest:
         HTTP Method = POST
         Request URI = /requests
          Parameters = {userId=[xianlinbox]}
             Headers = {Content-Type=[application/json], Accept=[application/json]}

             Handler:
                Type = com.xianlinbox.api.ApiController
              Method = public com.xianlinbox.api.Request com.xianlinbox.api.ApiController.post(java.lang.String,java.lang.String)

               Async:
   Was async started = false
        Async result = null

  Resolved Exception:
                Type = null

        ModelAndView:
           View name = null
                View = null
               Model = null

            FlashMap:

MockHttpServletResponse:
              Status = 201
       Error message = null
             Headers = {Content-Type=[application/json;charset=UTF-8]}
        Content type = application/json;charset=UTF-8
                Body = {"userId":"xianlinbox","requestId":"1","requestType":"POST","message":"this is the message"}
       Forwarded URL = null
      Redirected URL = null
             Cookies = []

看完了测试, 来简单的看下具体的实现代码:
Java代码   收藏代码
  1. @Controller  
  2. public class ApiController {  
  3.   
  4.     @RequestMapping(value = "/requests/{requestId}", method = RequestMethod.GET)  
  5.     @ResponseBody  
  6.     public Request get(@PathVariable String requestId, @RequestParam(value = "userId") String userId) {  
  7.         return new Request(userId, requestId, "GET");  
  8.     }  
  9.   
  10.     @RequestMapping(value = "/requests", method = RequestMethod.POST)  
  11.     @ResponseBody  
  12.     @ResponseStatus(value = HttpStatus.CREATED)  
  13.     public Request post(@RequestParam(value = "userId") String userId, @RequestBody String content) {  
  14.         Request request = new Request(userId, "1""POST");  
  15.         request.setMessage(content);  
  16.         return request;  
  17.     }  
  18. }  

  • 使用RequestMapping定义URL
  • 使用@ResponseBody表示返回json
  • 使用@PathVariable 获取路径参数
  • 使用@RequestParam获取request payload中的参数
  • 使用@RequestBody获取request body
  • 使用@ResponseStatus(value = HttpStatus.CREATED),定义返回的HTTP STATUS CODE


该Demo的所有代码: https://github.com/xianlinbox/TDD_Demo/tree/master/spring-ws-rest
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`spring-boot-starter-jersey` 是 Spring Boot 官方提供的一个集成 JAX-RS (Jersey) 的 Starter,通过引入该 Starter 可以很方便的集成 JAX-RS 技术栈。 Jersey 是 JAX-RS 的一个参考实现,它提供了一个基于 Servlet 的 Web 容器,使得开发人员可以很容易地创建 RESTful Web 服务。在使用 Spring Boot 集成 Jersey 时,我们只需要引入 `spring-boot-starter-jersey` 依赖就可以了。 下面是一个示例,演示了如何在 Spring Boot 中使用 Jersey: 1. 添加依赖 在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jersey</artifactId> </dependency> ``` 2. 创建 REST 资源类 创建一个 REST 资源类,并使用 `@Path` 和 `@Produces` 注解定义资源路径和返回数据的类型。 ```java import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String sayHello() { return "Hello, World!"; } } ``` 3. 创建 Application 类 创建一个 `Application` 类,并使用 `@ApplicationPath` 注解定义应用程序的根路径。 ```java import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; import javax.ws.rs.ApplicationPath; @Component @ApplicationPath("/api") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(HelloResource.class); } } ``` 4. 启动应用程序并测试 启动应用程序,访问 URL http://localhost:8080/api/hello,您应该可以看到 "Hello, World!" 这个字符串。 这就是在 Spring Boot 中集成 Jersey 的基本步骤。您可以根据您的需求,使用更多的 JAX-RS 注解来定义 RESTful 资源类的行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值