• Spring Boot开发RESTful接⼝服务及单元测试


    Spring Boot开发RESTful接⼝服务及单元测试

    常用注解解释说明:

    • @Controller :修饰class,⽤来创建处理http请求的对象
    • @RestController :Spring4之后加⼊的注解,原来在 @Controller 中返回json需要@ResponseBody 来配合,如果直接⽤ @RestController 替代 @Controller 就不需要再配置 @ResponseBody ,默认返回json格式。
    • @RequestMapping :配置url映射

    下⾯我们尝试使⽤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实体定义

    package com.kingram.springboot.beans;
    
    import lombok.Data;
    
    @Data
    public class User {
        private Long id;
        private String name;
        private Integer age;
    }
    

    接口实现

    package com.kingram.springboot.controller;
    
    import com.kingram.springboot.beans.User;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.*;
    
    @RestController
    @RequestMapping(value = "/users")
    public class UserController {    
        // 创建线程安全的Map    
        private static Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());    
        
        @RequestMapping(value = "/", method = RequestMethod.GET)    
        public List<User> getUserList() {           
            List<User> r = new ArrayList<>(users.values());        
            return r;   
        }    
        
        @RequestMapping(value = "/", method = RequestMethod.POST)    
        public String postUser(@ModelAttribute User user) {     
            users.put(user.getId(), user);        
            return "success";    
        }    
        
        @RequestMapping(value = "/{id}", method = RequestMethod.GET)    
        public User getUser(@PathVariable Long id) { 
            return users.get(id);    
        }    
        
        @RequestMapping(value = "/{id}", method = RequestMethod.PUT)    
        public String putUser(@PathVariable Long id, @ModelAttribute User user) {  
            User u = users.get(id);        
            u.setName(user.getName());        
            u.setAge(user.getAge());        
            users.put(id, u);        
            return "success";    
        }    
        
        @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) 
        public String deleteUser(@PathVariable Long id) {
            users.remove(id);        
            return "success";    
        }
    }
    

    测试⽤例

    package com.kingram.springboot;
    
    import com.kingram.springboot.controller.UserController;
    
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.RequestBuilder;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import static org.hamcrest.core.IsEqual.equalTo;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    
    @SpringBootTest
    @DisplayName("Test UserController")  
    public class UserControllerTest {    
        
        private MockMvc mvc;    
        
        @BeforeEach    
        void setUp() {        
            mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();    
        }    
        
        @Test      
        void testUserController() throws Exception {        
           
           RequestBuilder request;        
           
           // (1)get查⼀下user列表,应该为空        
            request = get("/users/");
            mvc.perform(request).andExpect(status().isOk()).andExpect(content().string(equalTo("[]")));        
            
            // (2)post提交⼀个user        
            request = post("/users/").param("id", "1").param("name", "张三").param("age", "50");
            mvc.perform(request).andExpect(content().string(equalTo("success")));        
            
            //(3)get获取user列表,应该有刚才插⼊的数据        
            request = get("/users/");        
            mvc.perform(request).andExpect(status().isOk()).andExpect(content().string(equalTo("[{"id":1,"name":"张三","age":50}]")));       
            
            // (4)put修改id为1的user        
            request = put("/users/1").param("name", "李四").param("age","30");        
            mvc.perform(request).andExpect(content().string(equalTo("success")));        
            
            // (5)get⼀个id为1的user        
            request = get("/users/1");        
            mvc.perform(request).andExpect(content().string(equalTo("{"id":1,"name":"李四","age":30}")));        
            
            // (6)del删除id为1的user        
            request = delete("/users/1");        
            mvc.perform(request).andExpect(content().string(equalTo("success")));        
            
            // (7)get查⼀下user列表,应该为空        
            request = get("/users/"); 
            mvc.perform(request).andExpect(status().isOk()) .andExpect(content().string(equalTo("[]")));    
        }
    }
    

    参考资料

    程序猿DD / SpringBoot-Learning

  • 相关阅读:
    Laravel 底层原理:门面(Facades)
    用 PHP和Golang 来刷leetCode 之 无重复字符 最长子串
    今天发现一个好用的查询IP地址的工具,记录一波
    Ubuntu下安装SDL
    敏捷宣言
    python 读取xml文档
    每个程序员都必须遵守的编程原则
    作为Web开发人员,我为什么喜欢Google Chrome浏览器
    爬虫
    Python为什么要self
  • 原文地址:https://www.cnblogs.com/Kingram/p/11808815.html
Copyright © 2020-2023  润新知