zoukankan      html  css  js  c++  java
  • spring boot 单元测试使用new MockMvc和@RunWith+@AutoConfigureMockMvc注解的区别

    在单元测试中用以上两种都能实现,但是@RunWith注解还可以实现代码中的依赖注入(前者不能)

    单测代码如下

    Slf4j
    @RestController
    @RequestMapping("/rest")
    public class ArticleRestController {
    
        @Resource
        ArticleRestService articleRestService;
    
        /**
         * 增加一篇文章
         *
         * @param article
         * @return
         */
        // @RequestMapping(value = "/article", method = RequestMethod.POST, produces = "application/json")
        @PostMapping("/article")
        public AjaxResponse saveArticle(@RequestBody Article article) {
            articleRestService.saveArticle(article);
            return AjaxResponse.success(article);
        }
    }
    

    自定义MockMvc做法,会报出空指针异常

    @Slf4j
    @SpringBootTest
    public class ArticleRestControllerTest {
    
        //mock对象
        private MockMvc mockMvc;
    
        //mock对象初始化
        @BeforeEach
        public void setUp() {
            mockMvc = MockMvcBuilders.standaloneSetup(new ArticleRestController()).build();
        }
    
        //测试方法
        @Test
        public void saveArticle() throws Exception {
    
            String article = "{
    " +
                    "    "id": 1,
    " +
                    "    "author": "zimug",
    " +
                    "    "title": "手摸手教你开发spring boot",
    " +
                    "    "content": "c",
    " +
                    "    "reader":[{"name":"zimug","age":18},{"name":"kobe","age":37}]
    " +
                    "}";
            MvcResult result = mockMvc.perform(
                    MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/article")
                    .contentType("application/json").content(article))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug"))
                    .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18))
                    .andDo(print())
                    .andReturn();
    
            log.info(result.getResponse().getContentAsString());
    
        }
    }
    

    使用@RunWith(SpringRunner.class)注解

    @Slf4j
    @RunWith(SpringRunner.class)
    @AutoConfigureMockMvc   //相当于new MockMvc
    @SpringBootTest
    public class ArticleRestControllerTest2 {
    
        //mock对象
        @Resource
        private MockMvc mockMvc;
    
        @Resource
        ArticleRestService articleRestService;
    
        //测试方法
        @Test
        public void saveArticle() throws Exception {
    
            String article = "{
    " +
                    "    "id": 1,
    " +
                    "    "author": "zimug",
    " +
                    "    "title": "手摸手教你开发spring boot",
    " +
                    "    "content": "c",
    " +
                    "    "reader":[{"name":"zimug","age":18},{"name":"kobe","age":37}]
    " +
                    "}";
            MvcResult result = mockMvc.perform(
                    MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/article")
                    .contentType("application/json").content(article))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug"))
                    .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18))
                    .andDo(print())
                    .andReturn();
    
            log.info(result.getResponse().getContentAsString());
    
        }
    }
    

    不会报出异常

    解析

    • RunWith方法为我们构造了一个的Servlet容器运行运行环境,并在此环境下测试。然而为什么要构建servlet容器?因为使用了依赖注入,注入了MockMvc对象,而在上一个例子里面是我们自己new的。
    • 而@AutoConfigureMockMvc注解,该注解表示 MockMvc由spring容器构建,你只负责注入之后用就可以了。这种写法是为了让测试在Spring容器环境下执行。
    • Spring的容器环境是什么呢?比如常见的 Service、Dao 都是Spring容器里的bean,装载到容器里面都可以使用@Resource和@Autowired来注入引用。
    • 简单的说:如果你单元测试代码使用了依赖注入就加上@RunWith,如果你不是手动new MockMvc对象就加上@AutoConfigureMockMvc
  • 相关阅读:
    领导者是梦想家,却不能只是梦想家
    8i查询DBA_FREE_SPACE视图极慢的问题
    11g 新特性IGNORE_ROW_ON_DUPKEY_INDEX提示
    ORA00600:[qctcte1]内部错误一例
    利用FORCE_MATCHING_SIGNATURE捕获非绑定变量SQL
    Does DB Time include wait on cpu queue time?
    对于OCM考试的几点意见和建议
    rman hang on SQL*Net message from client
    ddl操作是否会产生undo?
    ORA07445: [__lwp_kill()+8] [SIGIOT]错误一例
  • 原文地址:https://www.cnblogs.com/zhoushiya/p/12748777.html
Copyright © 2011-2022 走看看