48. spring boot单元测试restfull API【从零开始学Spring Boot】
回顾并详细说明一下在在之前章节中的中使用的@Controller、@RestController、@RequestMapping注解。如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建议先看一下之前的内容。
下面我们尝试使用Spring MVC来实现一组对User对象操作的RESTful API,配合注释详细说明在Spring MVC中如何映射HTTP请求、如何传参、如何编写单元测试。
* RESTful API具体设计如下:*
|
请求类型 |
URL |
功能说明 |
|
GET |
/users |
查询用户列表 |
|
POST |
/users |
创建一个用户 |
|
GET |
/users/id |
根据id查询一个用户 |
|
PUT |
/users/id |
根据id更新一个用户 |
|
DELETE |
/users/id |
根据id删除一个用户 |
User实体定义:
public class User {
privatelongid;
private String name;
private Integer age;
// 省略setter和getter
}
实现对User对象的操作接口:
package com.kfit.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.kfit.demo.User;
@RestController
@RequestMapping(value="/users")// 通过这里配置使下面的映射都在/users下
public class UserController {
//这里为了方便测试,直接将数据存储在map中,实际请从数据库获取.
private static Map<Long,User> users = Collections.synchronizedMap(new HashMap<Long,User>());
/**
* 返回所有的用户.
* @return
*/
@RequestMapping(value="", method=RequestMethod.GET)
public List<User> getUserList() {
// 处理"/users/"的GET请求,用来获取用户列表
// 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递
List<User> r = new ArrayList<User>(users.values());
returnr;
}
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public User getUser(@PathVariable Long id) {
// 处理"/users/{id}"的GET请求,用来获取url中id值的User信息
// url中的id可通过@PathVariable绑定到函数的参数中
returnusers.get(id);
}
/**
* post 保存用户.
* @param user
* @return
*/
@RequestMapping(value = "",method=RequestMethod.POST)
public String postUser(User user){
// 处理"/users/"的POST请求,用来创建User
//@ModelAttribute User user
// 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数
users.put(user.getId(), user);
return"success";
}
/**
* 使用put 进行更新用户.
* @param id
* @param user
* @return
*/
@RequestMapping(value="/{id}",method=RequestMethod.PUT)
public String putUser(@PathVariable Long id,User user){
// 处理"/users/{id}"的GET请求,用来获取url中id值的User信息
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return"success";
}
/**
* 使用delete删除用户.
* @param id
* @return
*/
@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
// 处理"/users/{id}"的DELETE请求,用来删除User
// url中的id可通过@PathVariable绑定到函数的参数中
users.remove(id);
return"success";
}
}
下面针对该Controller编写测试用例验证正确性,具体如下。当然也可以通过浏览器插件等进行请求提交验证:
package com.kfit.demo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.kfit.controller.UserController;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes=MockServletContext.class)//MockServletContext.class
@WebAppConfiguration
public class UserControllerTest extends MockMvcResultMatchers{
//模拟mvc对象类.
private MockMvc mvc;
@Before
public void setup(){
/*
* MockMvcBuilders使用构建MockMvc对象.
*/
mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
}
@Test
public void testUserController() throws Exception{
RequestBuilder request = null;
//1. get 以下user列表,应该为空》
//1、构建一个get请求.
request = MockMvcRequestBuilders.get("/users");
mvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().string("[]"))
;
System.out.println("UserControllerTest.testUserController().get");
// 2、post提交一个user
request = MockMvcRequestBuilders.post("/users")
.param("id","1")
.param("name","林峰")
.param("age","20")
;
mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("success"));
// 3、get获取user列表,应该有刚才插入的数据
request = MockMvcRequestBuilders.get("/users");
mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("[{\"id\":1,\"name\":\"林峰\",\"age\":20}]"));
// 4、put修改id为1的user
request = MockMvcRequestBuilders.put("/users/1")
.param("name", "林则徐")
.param("age", "30");
mvc.perform(request)
.andExpect(content().string("success"));
// 5、get一个id为1的user
request = MockMvcRequestBuilders.get("/users/1");
mvc.perform(request)
.andExpect(content().string("{\"id\":1,\"name\":\"林则徐\",\"age\":30}"));
// 6、del删除id为1的user
request = MockMvcRequestBuilders.delete("/users/1");
mvc.perform(request)
.andExpect(content().string("success"));
// 7、get查一下user列表,应该为空
request = MockMvcRequestBuilders.get("/users");
mvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().string("[]"));
}
}
至此,我们通过引入web模块(没有做其他的任何配置),就可以轻松利用Spring MVC的功能,以非常简洁的代码完成了对User对象的RESTful API的创建以及单元测试的编写。
【Spring Boot 系列博客】
0)前言【从零开始学Spring Boot】 :
http://412887952-qq-com.iteye.com/blog/2291496
(1)spring boot起步之Hello World【从零开始学Spring Boot】:
http://412887952-qq-com.iteye.com/blog/2291500
(2)Spring Boot返回json数据【从零开始学Spring Boot】
http://412887952-qq-com.iteye.com/blog/2291508
(15)Spring Boot使用Druid和监控配置【从零开始学Spring Boot】
http://412887952-qq-com.iteye.com/blog/2292362
16)Spring Boot使用Druid(编程注入)【从零开始学Spring Boot】
http://412887952-qq-com.iteye.com/blogs/2292376
(17)Spring Boot普通类调用bean【从零开始学Spring Boot】:
http://412887952-qq-com.iteye.com/blog/2292388
......
(35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
http://412887952-qq-com.iteye.com/blog/2294942
(42)Spring Boot多数据源【从零开始学Spring Boot】 
http://412887952-qq-com.iteye.com/blog/2302997
(43). Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
47. Spring Boot发送邮件【从零开始学Spring Boot】 
48. spring boot单元测试restfull API【从零开始学Spring Boot】的更多相关文章
- 72.spring boot讨论群【从零开始学Spring Boot】
[从零开始学习Spirng Boot-常见异常汇总] 如果您碰到什么问题,您可以加群进行探讨,在群里有加入的都是Spring Boot志同道合的朋友: Spring Boot QQ交流群:193341 ...
- 59. Spring Boot Validator校验【从零开始学Spring Boot】
大纲: (1) 入门例子: (2) 国际化: (3) 在代码中添加错误信息: (1) 入门例子: Validator主要是校验用户提交的数据的合理性的,比如是否为空了,密码长度是否大于6位,是否是纯数 ...
- (6)Spring Boot datasource - mysql【从零开始学Spring Boot】
在任何一个平台都逃离不了数据库的操作,那么在spring boot中怎么接入数据库呢? 很简单,我们需要在application.properties进行配置一下,application.proper ...
- (3)Spring Boot热部署【从零开始学Spring Boot】
在编写代码的时候,你会发现我们只是简单把打印信息改变了下,就需要重新部署,如果是这样的编码方式,那么我们估计一天下来之后就真的是打几个Hello World之后就下班了.那么如何解决热部署的问题呢?那 ...
- (42)Spring Boot多数据源【从零开始学Spring Boot】
我们在开发过程中可能需要用到多个数据源,我们有一个项目(MySQL)就是和别的项目(SQL Server)混合使用了.其中SQL Server是别的公司开发的,有些基本数据需要从他们平台进行调取,那么 ...
- 84. Spring Boot集成MongoDB【从零开始学Spring Boot】
至于MongoDB网上有很多相关的资料,所以在这里不进行过多的介绍,我们在这里主要是介绍下如何将mongodb与spring boot结合使用.本节大纲: (1) 准备工作: (2) 新建一个mave ...
- Spring Boot配置ContextPath【从零开始学Spring Boot】
Spring boot默认是/ ,这样直接通过http://ip:port/就可以访问到index页面,如果要修改为http://ip:port/path/ 访问的话,那么需要在Application ...
- 86. Spring Boot集成ActiveMQ【从零开始学Spring Boot】
在Spring Boot中集成ActiveMQ相对还是比较简单的,都不需要安装什么服务,默认使用内存的activeMQ,当然配合ActiveMQ Server会更好.在这里我们简单介绍怎么使用,本节主 ...
- 85. Spring Boot集成RabbitMQ【从零开始学Spring Boot】
这一节我们介绍下Spring Boot整合RabbitMQ,对于RabbitMQ这里不过多的介绍,大家可以参考网络上的资源进行安装配置,本节重点是告诉大家如何在Spring Boot中使用Rabbit ...
随机推荐
- StackOverflow 创始人关于如何高效编程的清单
这是 StackOverflow 联合创始人 Jeff Atwood 注释的十戒.程序员普遍有很强的自尊心,都应该看看本文,打印下来时刻提醒自己. “无我编程”发生在开发阶段,表现为技术团队经常通过同 ...
- Q - Euclid in Manhattan(欧几里德距离==曼哈顿距离?)
Desciption Consider a set of n points in a 2-D plane with integer coordinates. There are various way ...
- ACM_求N^N的前5位数和后5位数(数论)
NNNNN Time Limit: 2000/1000ms (Java/Others) Problem Description: 对于整数N,求N^N的前5位和后5位(1057题加强版) Input: ...
- Linux环境下安装JDK并配置环境变量
首先查看是否已经安装了JDK并配置环境变量. [root@dhcc_plat opt]# java -version -bash: java: command not found [root@dhcc ...
- Jsp四个作用域page、request、session和application的区别
1.简单说 page指当前页面.在一个jsp页面里有效 2.request 指从http请求到服务器处理结束,返回响应的整个过程.在这个过程中使用forward方式跳转多个jsp.在这些页面里你都可 ...
- Unity笔记(3)自学第二天
学习记录: 界面使用: 脚本使用: 脚本注意点:
- (2)左右值初探与auto类型说明符
这篇文章的起因是下面这两段代码,出自<C++ primer 5th>中文版P62页: auto &h =42;//错误,不能为非常量引用绑定字面值 const auto & ...
- Tornado引入静态css、js文件
一.静态路径 template_path=os.path.join(os.path.dirname(__file__), "templates") 这里是设置了模板的路径,放置模板 ...
- bootstrap datatable 数据刷新问题
在项目中,页面初始化的时候,通过通过向后台请求数据,页面初始化完之后,datatable是有数据的,当我点击页面的搜索按钮(按照时间过滤数据),datatable的数据要能重新刷新或者重载:这一点,我 ...
- 用 webpack 实现持久化缓存
什么是持久化缓存? 原文链接https://sebastianblade.com/using-webpack-to-achieve-long-term-cache/ 缓存(cache)一直是前端性能优 ...