(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>

  (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;
    }
}

  选中要测试的类 -> 右键 -> 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));
    }

}

  运行如下:

  (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 () -> {};
    }
}

  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出错");
    }
}

  运行结果如下:

  不在测试环境无法获取@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"));
    }
}

  运行结果如下:

  删除测试环境的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"));
    }
}

  运行结果如下:

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

  接口UserMapper.java

package com.edu.spring.springboot.mapper;

public interface UserMapper {
    public Integer addUser(String username);
}

  测试类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));
    }

}

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

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));
    }

}

  运行结果如下:

  (三)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;
    }
}

  (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);
    }

}

  运行结果如下:

  (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"));
    }

}

  运行结果如下:

  假如在 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"));
    }

}

  运行结果如下:

  总结:

  @SpringBootTest 会加载整个spring容器

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

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

  @SpringBootTest 和 @WebMvcTest不能同时使用

  

原文地址:https://www.cnblogs.com/javasl/p/12039985.html

时间: 2024-10-13 08:59:47

(001)springboot中测试的基础知识以及接口和Controller的测试的相关文章

Java中String的基础知识

Java中String的基础知识 ==与equal的区别 基本数据类型,指的是java中的八种基本数据结构(byte,short,char,int,long,float,double,boolean),一般的比较是使用的 ==,比较的是他们的值. 复合数据类型(类) ==比较的是两个对象的引用,可以理解为在内存中的地址,除非是同一个new出来的对象,他们的 ==为true,否则,都为false. equal是object中的方法.object中的实现如下,内部还是使用==实现,也就是说,如果一个

ASP.NET中的C#基础知识

ASP.NET中的C#基础知识 说明:asp.net作为一种开发框架现在已经广为应用,其开发的基础除了前端的html.css.JavaScript等后端最重要的语言支持还是C#,下面将主要用到的基础知识做一个总结,方面后面的学习. 一.C#是一种面向对象的变成语言,主要用于开发可以在.net平台上运行的应用程序.是一种强类型语言,一次每个变量都必须具有声明类型.C#中有两种数据类型:值类型和引用类型.(其中值类型用于存储值,引用类型用于存储实际数据的引用). 1.值类型 值类型表示实际的数据,存

day29—JavaScript中DOM的基础知识应用

转行学开发,代码100天--2018-04-14 JavaScript中DOM操作基础知识即对DOM元素进行增删改操作.主要表现与HTML元素的操作,以及对CSS样式的操作.其主要应用知识如下图: 通过对DOM的基本了解,还要通过代码实现对DOM的操作. 1.childNodes + nodeType 与children的区别 <ul id= "ull"> <li>1</li> <li>2</li> <li>3&l

MVVM设计模式基础知识--INotifyPropertyChanged接口

在.NET平台上,数据绑定是一项令人十分愉快的技术.利用数据绑定能减少代码,简化控制逻辑. 通常,可以将某个对象的一个属性绑定到一个可视化的控件上,当属性值改变时,控件上的显示数据也随之发生变化.要实现这一功能,只需要为自定义对象实现 INotifyPropertyChanged 接口即可.此接口中定义了 PropertyChanged 事件,我们只需在属性值改变时触发该事件即可. INotifyPropertyChanged 接口是 WPF/Silverlight 开发中非常重要的接口, 它构

PHP中oop面向对象基础知识(一)

                                                                                    OOP 基础知识汇总(一) >>>你需要了解以下概念面向对象&面向过程概念:  面向过程:专注于解决一个问题的过程.面向过程的最大特点,是由一个一个的函数去解决处理这个问题的一系列过程.  面向对象:专注于由哪个对象来处理一个问题.面向对象的最大特点,是有一个个具有属性和功能的类,从类中拿到对象,进而处理问题. [

Java中浮点数的基础知识

偶然查看Math.round的JDK 1 public static int round(float a) { 2 if (a != 0x1.fffffep-2f) // greatest float value less than 0.5 3 return (int)floor(a + 0.5f); 4 else 5 return 0; 6 } 注释说0x1.fffffep-2f是最接近0.5的float类型的小数,咦,科学计数法用e表示指数我是知道的,但是这个p是什么鬼.可能有的读者还会问,

javascript中BOM部分基础知识总结

一.什么是BOM BOM(Browser Object Document)即浏览器对象模型. BOM提供了独立于内容 而与浏览器窗口进行交互的对象: 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是window: BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性: BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分. 二.学习BOM学什么 我们将学到与浏览器窗口交互的一些对象,例如

测试必备基础知识总结

什么是软件测试 软件测试是使用人工操作或者软件自动运行的方式来检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别的过程. 本质:软件测试是为发现软件错误而执行程序的过程. 例如场景:淘宝网用户登陆 大家都有在淘宝购物的经历吧,如果想要在淘宝进行购物,就必须登陆后才能进行. 那么能够登陆的前提是什么呢?必须是淘宝网的注册用户. 登陆的步骤是什么呢?在下图1中输入已经注册的用户名>输入已设定的密码>点击“登陆”按钮,步骤非常简单. 大家也一定会遇到过用户名和密码输入错误而无法登陆的情况,此

可靠性测试的基础知识——软件可靠性测试

可靠性测试 可靠性测试概念 对软件可靠性进行定量的评估或验证,为了达到和验证软件的可靠性定量要求而对软件进行的测试 软件可靠性测试的目的 (1)通过在有使用代表性的环境中执行软件,以证实软件需求是否正确实现. (2)为进行软件可靠性估计采集准确的数据,预测软件在实际运行中的可靠性. 估计软件可靠性一般可分为四个步骤,即数据采集.模型选择.模型拟合以及软件可靠性评估.可以认为,数据采集是整个软件可靠性估计工作的基础,数据的准确与否关系到软件可靠性评估的准确度. (3)通过软件可靠性测试找出所有对软