zoukankan      html  css  js  c++  java
  • (001)springboot中测试的基础知识以及接口和Controller的测试

      (一)springboot中测试的基础知识

      (1)添加starter-test依赖,范围指定为test,只在执行测试时生效

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

      完整pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.edu.spring</groupId>
        <artifactId>springboot_web</artifactId>
        <version>1.0.0</version>
    
        <name>springboot_web</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    View Code

      (2)新建类UserDao.java,并添加测试类

    package com.edu.spring.springboot.dao;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class UserDao {
    
        public Integer  addUser(String username){
            System.out.println("user dao addUser["+username+"]");
            if(username==null){
                return 0;
            }
            return 1;
        }
    }
    View Code

      选中要测试的类 -> 右键 -> new -> 输入ju,选择JUnit Test Case  -> next -> 选择填写正确信息 -> next -> 选择测试的方法 -> finish

       UserDaoTest.java,测试类需要添加注解@RunWith(SpringRunner.class)、@SpringBootTest

    package com.edu.spring.springboot.dao;
    
    import org.junit.Assert;
    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.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserDaoTest {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        public void testAddUser() {
            Assert.assertEquals(Integer.valueOf(1), userDao.addUser("root"));
            Assert.assertEquals(Integer.valueOf(0), userDao.addUser(null));
        }
    
    }
    View Code

      运行如下:

       (3)在测试环境创建bean需要用@TestConfiguration,并且该注解只在测试环境下有效

      TestBeanConfiguration.java(src/test/java),创建Runnable类型的bean

    package com.edu.spring.springboot.dao;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.boot.test.context.TestConfiguration;
    
    @TestConfiguration
    public class TestBeanConfiguration {
    
        @Bean
        public Runnable createRunnable(){
            return () -> {};
        }
    }
    View Code

      ApplicationContextTest.java(src/test/java),指定测试环境的配置类 @SpringBootTest(classes=TestBeanConfiguration.class)

    package com.edu.spring.springboot.dao;
    
    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.context.ApplicationContext;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.util.Assert;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes=TestBeanConfiguration.class)
    public class ApplicationContextTest {
    
        @Autowired
        private ApplicationContext context;
        
        @Test
        public void testNull(){
            Assert.notNull(context.getBean(Runnable.class),"获取Runnable.class的bean出错");
        }
    }
    View Code

      运行结果如下:

       不在测试环境无法获取@TestConfiguration中创建的bean,如下图

      (4)springboot会优先加载测试环境下的application.properties,测试环境下没有才会加载正常环境下的

      application.properties(src/test/resources)

    app.name=springboottest

      EnvTest.java(src/test/java),测试环境使用ConfigurableEnvironment获取配置文件属性

    package com.edu.spring.springboot.dao;
    
    
    import org.junit.Assert;
    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.core.env.ConfigurableEnvironment;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class EnvTest {
        
        @Autowired
        private ConfigurableEnvironment env;
        
        @Test
        public void testValue(){
            Assert.assertEquals("springboottest",env.getProperty("app.name"));
        }
    }
    View Code

      运行结果如下:

       删除测试环境的application.properties,在正常环境的application.properties添加如下配置

    app.name=springboot

      EnvTest.java修改为:

    Assert.assertEquals("springboot",env.getProperty("app.name"));

      运行结果如下:

      (5)运行时指定配置@SpringBootTest(properties = {"app.admin.name=zhangsan","app.admin.passwd=123456"})

      EnvTest.java

    package com.edu.spring.springboot.dao;
    
    
    import org.junit.Assert;
    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.core.env.ConfigurableEnvironment;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(properties = {"app.admin.name=zhangsan","app.admin.passwd=123456"})
    public class EnvTest {
        
        @Autowired
        private ConfigurableEnvironment env;
        
        @Test
        public void testValue(){
            Assert.assertEquals("zhangsan",env.getProperty("app.admin.name"));
            Assert.assertEquals("123456",env.getProperty("app.admin.passwd"));
        }
    }
    View Code

      运行结果如下:

      (二)springboot中测试接口,使用注解@MockBean 和 BDDMockito类

      接口UserMapper.java

    package com.edu.spring.springboot.mapper;
    
    public interface UserMapper {
        public Integer addUser(String username);
    }
    View Code

      测试类UserMapperTest.java,@MockBean注入接口,BDDMockito给出预测

    package com.edu.spring.springboot.mapper;
    
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.BDDMockito;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserMapperTest {
    
        @MockBean
        private UserMapper userMapper;
        
        @Test(expected=NullPointerException.class)
        public void createUserTest(){
            
            BDDMockito.given(userMapper.addUser("admin")).willReturn(Integer.valueOf(1));
            BDDMockito.given(userMapper.addUser("")).willReturn(Integer.valueOf(0));
            BDDMockito.given(userMapper.addUser(null)).willThrow(NullPointerException.class);
            
            Assert.assertEquals(Integer.valueOf(1), userMapper.addUser("admin"));
            Assert.assertEquals(Integer.valueOf(0), userMapper.addUser(""));
            Assert.assertEquals(Integer.valueOf(0), userMapper.addUser(null));
        }
    
    }
    View Code

      或者在初始化方法中给出预测:

    package com.edu.spring.springboot.mapper;
    
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.BDDMockito;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.boot.test.mock.mockito.MockBean;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserMapperTest {
    
        @MockBean
        private UserMapper userMapper;
        
        @Before
        public void init(){
            BDDMockito.given(userMapper.addUser("admin")).willReturn(Integer.valueOf(1));
            BDDMockito.given(userMapper.addUser("")).willReturn(Integer.valueOf(0));
            BDDMockito.given(userMapper.addUser(null)).willThrow(NullPointerException.class);
        }
        
        @Test(expected=NullPointerException.class)
        public void createUserTest(){
            Assert.assertEquals(Integer.valueOf(1), userMapper.addUser("admin"));
            Assert.assertEquals(Integer.valueOf(0), userMapper.addUser(""));
            Assert.assertEquals(Integer.valueOf(0), userMapper.addUser(null));
        }
    
    }
    View Code

      运行结果如下:

      (三)springboot中测试Controller的两种方式:TestRestTemplate 和 MockMvc,这里从构建测试环境分3种进行说明

      BookController.java

    package com.edu.spring.springboot;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class BookController {
    
        @GetMapping("/book/home")
        public String home(){
            return "book home";
        }
        
        @GetMapping("/book/show")
        public String show(String id){
            return "book"+id;
        }
    }
    View Code

      (1)@SpringBootTest注解,指定webEnvironment 和 注入TestRestTemplate

      BookControllerTest.java

    package com.edu.spring.springboot;
    
    import org.junit.Assert;
    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.boot.test.context.SpringBootTest.WebEnvironment;
    import org.springframework.boot.test.web.client.TestRestTemplate;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
    public class BookControllerTest {
    
        @Autowired
        private TestRestTemplate restTemplate;
        
        @Test
        public void testHome() {
            String actual=restTemplate.getForObject("/book/home",String.class);
            Assert.assertEquals("book home", actual);
        }
        
        @Test
        public void testShow() {
            String actual=restTemplate.getForObject("/book/show?id=100",String.class);
            Assert.assertEquals("book100", actual);
        }
    
    }
    View Code

      运行结果如下:

      (2)@WebMvcTest注解,指定controllers 和 注入MockMvc 

      BookControllerTest2.java

    package com.edu.spring.springboot;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    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.result.MockMvcResultMatchers;
    
    @RunWith(SpringRunner.class)
    @WebMvcTest(controllers=BookController.class)
    public class BookControllerTest2 {
    
        @Autowired
        private MockMvc mockMvc;
        
        @Test
        public void testHome() throws Exception {
            mockMvc.perform(MockMvcRequestBuilders.get("/book/home")).andExpect(MockMvcResultMatchers.status().isOk());
            mockMvc.perform(MockMvcRequestBuilders.get("/book/home")).andExpect(MockMvcResultMatchers.content().string("book home"));
        }
        
        @Test
        public void testShow() throws Exception{
            
            mockMvc.perform(MockMvcRequestBuilders.get("/book/show").param("id","100")).andExpect(MockMvcResultMatchers.status().isOk());
            mockMvc.perform(MockMvcRequestBuilders.get("/book/show").param("id","100")).andExpect(MockMvcResultMatchers.content().string("book100"));
        }
    
    }
    View Code

      运行结果如下:

      假如在 BookController.java 中注入 UserDao,即添加如下代码,再次测试会报错,因为@WebMvcTest不会加载整个spring容器

    @Autowired UserDao userDao;

      运行结果如下

      (3)使用@SpringBootTest、@AutoConfigureMockMvc 注解,注入MockMvc

      BookControllerTest3.java

    package com.edu.spring.springboot;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    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.result.MockMvcResultMatchers;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class BookControllerTest3 {
    
        @Autowired
        private MockMvc mockMvc;
        
        @Test
        public void testHome() throws Exception {
            mockMvc.perform(MockMvcRequestBuilders.get("/book/home")).andExpect(MockMvcResultMatchers.status().isOk());
            mockMvc.perform(MockMvcRequestBuilders.get("/book/home")).andExpect(MockMvcResultMatchers.content().string("book home"));
        }
        
        @Test
        public void testShow() throws Exception{
            
            mockMvc.perform(MockMvcRequestBuilders.get("/book/show").param("id","100")).andExpect(MockMvcResultMatchers.status().isOk());
            mockMvc.perform(MockMvcRequestBuilders.get("/book/show").param("id","100")).andExpect(MockMvcResultMatchers.content().string("book100"));
        }
    
    }
    View Code

      运行结果如下:

      总结:

      @SpringBootTest 会加载整个spring容器

      @WebMvcTest 不需要运行在web环境下,但是需要指定controllers,这种方法只测试controller,不会加载整个spring容器

      如果依然使用MockMvc,需要添加@SpringBootTest 和 @AutoConfigureMockMvc注解 

      @SpringBootTest 和 @WebMvcTest不能同时使用

      

  • 相关阅读:
    【转】Windows7 下安装 JDK 7 时版本冲突问题解决
    【转】Android开发之旅:环境搭建及HelloWorld
    android开发板
    win7重装系统的配置步骤
    caffe 源码阅读
    caffe 源码阅读
    Python 图像处理: 生成二维高斯分布蒙版
    学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装
    学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装
    CMake 添加头文件目录,链接动态、静态库(添加子文件夹)
  • 原文地址:https://www.cnblogs.com/javasl/p/12039985.html
Copyright © 2011-2022 走看看