SpringBoot的测试方案

写完代码后,测试是必不可少的步骤,现在来介绍一下基于SpringBoot的测试方法。

基于SpringBoot框架写完相应功能的Controller之后,然后就可以测试功能是否正常,本博客列举MockMvcRestTemplate两种方式来测试。

准备代码

实体类Person

public class Person {
    private String id;

    private String name;

    public Person() {}

    public Person(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + "]";
    }

}

控制器PersonController

import javax.validation.Valid;

import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
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.test.springboottest.bean.Person;

@RestController
@RequestMapping("/person")
public class PersonController {

    /**
     * 使用对象方式传递数据
     * @param person 保存对象
     * @return
     */
    @RequestMapping(value="/add",method=RequestMethod.POST)
    public Person addUser(Person person){
        person.setId(UUID.randomUUID().toString().substring(0, 6));
        return person;
    }


    /**
     * 使用JSON方式传递数据
     * @param person 保存对象
     * @return
     */
    @RequestMapping(value="/addJson",method=RequestMethod.POST)
    public Person addUserByJson(@RequestBody Person person){
        person.setId(UUID.randomUUID().toString().substring(0, 6));
        return person;
    }

    @RequestMapping(value="/get/{id}",method=RequestMethod.GET)
    public Person getUser(@PathVariable String id){
        Person person = new Person("Mepper");
        person.setId(id);
        return person;
    }
}

上述代码即为简化版的数据的增查的功能。

MockMvc方式

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.springboottest.bean.Person;

@SpringBootTest//系统会自动加载Spring Boot容器
@RunWith(SpringRunner.class)
public class ControllerTest {

    //模拟http请求
    private MockMvc mockMvc;

    //用于将对象转换为json字符串
    private ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private WebApplicationContext context;

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

    //测试数据获取
    @Test
    public void getPerson(){
        try {
            mockMvc.perform(MockMvcRequestBuilders
                .get("/person/get/2018001") //请求的url,请求的方法是get
                .accept(MediaType.APPLICATION_JSON_UTF8))
                .andDo(print());//打印出请求和相应的内容
                .andReturn().getResponse().getContentAsString(); //将相应的数据转换为字符串
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //测试数据的添加
    @Test
    public void addPerson(){
        try {
            mockMvc.perform(MockMvcRequestBuilders
                .post("/person/add")
                .param("name", "Apple") //添加参数
                .accept(MediaType.APPLICATION_JSON_UTF8))
                .andDo(print());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //测试JSON字符串的保存
    @Test
    public void addPersonByJson(){
        try {
            Person person = new Person("Banana");
            String requestBody = mapper.writeValueAsString(person);
            mockMvc.perform(MockMvcRequestBuilders
                .post("/person/addJson")
                .contentType(MediaType.APPLICATION_JSON_UTF8)  //数据的格式
                .content(requestBody)  
                .accept(MediaType.APPLICATION_JSON_UTF8))
                .andDo(print());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • mockMvc.perform:执行一个RequestBuilder请求
  • MockMvcRequestBuilders.get:构造一个get请求。另外提供了其他的请求的方法,如:post、put、delete等
  • param:添加request的参数root的参数。假如使用需要发送json数据格式的时将不能使用这种方式,可见后面被@ResponseBody注解参数的解决方法
  • contentType:指定传递的数据类型
  • accept: 指定接受的数据类型
  • andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台(对返回的数据进行的判断)
  • andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理(对返回的数据进行的判断)

注意点

当使用JSON传递数据的时候,需要使用.contentType(MediaType.APPLICATION_JSON_UTF8).content(requestBody)的方式,
不然会发生org.springframework.http.converter.HttpMessageNotReadableException异常,因为相应方法只接受JSON数据格式。

RestTemplate方式

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.test.springboottest.bean.Person;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
public class ControllerRestTest {

    @Value("http://localhost:${local.server.port}/person")
    private String baseUrl;

    private RestTemplate restTemplate = new RestTemplate();

    @Test
    public void getPerson(){
        Person person=restTemplate.getForObject(baseUrl+"/get/001", Person.class);
        System.out.println(person);
    }

    @Test
    public void addPerson(){
        //当直接传递参数需要用map
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("name", "Aster");
        Person person=restTemplate.postForObject(baseUrl+"/add", paramMap, Person.class);
        System.out.println(person);
    }

    @Test
    public void addPersonByJson(){
        try{
            Person p = new Person("Banana");
            Person person=restTemplate.postForObject(baseUrl+"/addJson", p, Person.class);
            System.out.println(person);
        }catch (Exception e) {
            e.printStackTrace();
        }

    }
}

相比而言,RestTemplate比MockMvc更加简单,更加清晰。

相关推荐
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408191 小时前
如何在 Spring Boot 中启用定时任务
spring boot
测开小菜鸟3 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天4 小时前
java的threadlocal为何内存泄漏
java
caridle4 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^4 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋34 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx