目录

添加依赖与配置

ApplicationContext测试

Environment测试

MockBean测试

Controller测试

情况一

情况二

方法一

方法二


本文将对在Springboot中如何使用Junit进行单元测试进行简单示例和介绍,项目的完整目录层次如下图所示。

添加依赖与配置

为了保证测试的完整性,本工程POM文件中除引入Junit单元测试依赖外,还额外引入了用来测试JDBC和Controller的JPA和WEB依赖。


  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>1.5.6.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!-- 添加MySQL依赖 -->
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. </dependency>
  12. <!-- 添加JDBC依赖 -->
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-data-jpa</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <!-- 引入单元测试依赖 -->
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. </dependencies>

同时,在src/main/resources目录下添加核心配置文件application.properties,内容如下。


  1. #########################################################
  2. ### Spring DataSource -- DataSource configuration ###
  3. #########################################################
  4. spring.datasource.url=jdbc:mysql://localhost:3306/dev1?useUnicode=true&characterEncoding=utf8
  5. spring.datasource.driverClassName=com.mysql.jdbc.Driver
  6. spring.datasource.username=root
  7. spring.datasource.password=123456
  8. #########################################################
  9. ### Java Persistence Api -- Spring jpa configuration ###
  10. #########################################################
  11. # Specify the DBMS
  12. spring.jpa.database = MYSQL
  13. # Show or not log for each sql query
  14. spring.jpa.show-sql = true
  15. # Hibernate ddl auto (create, create-drop, update)
  16. spring.jpa.hibernate.ddl-auto = update
  17. # Naming strategy
  18. #[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]
  19. spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
  20. # stripped before adding them to the entity manager)
  21. spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

ApplicationContext测试

在Springboot中使用Junit进行单元测试的方法很简单,只需要在编写的单元测试类上添加两个注解:@RunWith(SpringRunner.class)和@SpringBootTest。


  1. @RunWith(SpringRunner.class) // 等价于使用 @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest(classes = { MyApplication.class, TestConfig.class })
  3. public class ApplicationContextTest {
  4. @Autowired
  5. private ApplicationContext context;
  6. @Autowired
  7. private UserDao userDao;
  8. @Test
  9. public void testUserDao() {
  10. userDao.addUser(18, "pengjunlee");
  11. }
  12. @Test
  13. public void testConfiguration() {
  14. Runnable bean = context.getBean(Runnable.class);
  15. Assert.assertNotNull(bean);
  16. bean.run();
  17. }
  18. }

UserDao定义如下。


  1. @Repository
  2. public class UserDao {
  3. @Autowired
  4. private JdbcTemplate jdbcTemplate;
  5. @Transactional
  6. public void addUser(Integer userAge, String userName) {
  7. String sql = "insert into tbl_user (age,name) values ('" + userAge + "','" + userName + "');";
  8. jdbcTemplate.execute(sql);
  9. }
  10. }

TestConfig定义如下。


  1. /**
  2. * @TestConfiguration注解的配置内的Bean仅在测试时装配
  3. */
  4. @TestConfiguration
  5. public class TestConfig {
  6. @Bean
  7. public Runnable createRunnable(){
  8. return ()->{
  9. System.out.println("This is a test Runnable bean...");
  10. };
  11. }
  12. }

提示:@SpringBootTest注解的classes可以指定用来加载Spring容器所使用的配置类,@TestConfiguration注解修饰的配置类内的Bean仅在测试的时候才会装配。

Environment测试

我们可以通过@SpringBootTest注解的properties属性向Environment中设置新的属性,也可以通过使用EnvironmentTestUtils工具类来向ConfigurableEnvironment中添加新的属性。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(properties = { "app.token=pengjunlee" })
  3. public class EnvironmentTest {
  4. @Autowired
  5. private Environment env;
  6. @Autowired
  7. private ConfigurableEnvironment cenv;
  8. @Before
  9. public void init() {
  10. EnvironmentTestUtils.addEnvironment(cenv, "app.secret=55a4b77eda");
  11. }
  12. @Test
  13. public void testEnvironment() {
  14. System.out.println(env.getProperty("spring.datasource.url"));
  15. Assert.assertEquals("pengjunlee", env.getProperty("app.token"));
  16. Assert.assertEquals("55a4b77eda", cenv.getProperty("app.secret"));
  17. }
  18. @Test
  19. @Ignore // 忽略测试方法
  20. public void testIgnore() {
  21. System.out.println("你看不见我...");
  22. }
  23. }

扩展:Junit测试用例执行顺序:@BeforeClass ==> @Before ==> @Test ==> @After ==> @AfterClass 。

注意:在使用Junit对Spring容器进行单元测试时,若在src/test/resources 目录下存在核心配置文件,Spring容器将会只加载src/test/resources 目录下的核心配置文件,而不再加载src/main/resources 目录下的核心配置文件。

MockBean测试

我们可以通过@MockBean注解来对那些未添加实现的接口进行模拟测试,预先设定好调用方法期待的返回值,然后再进行测试。

例如,有如下的IUserService接口,定义了一个getUserAge()方法用来根据用户的ID来查询用户的年龄。


  1. public interface IUserService {
  2. Integer getUserAge(Long userId);
  3. }

使用@MockBean来对IUserService接口进行模拟测试,测试代码如下。


  1. @RunWith(SpringRunner.class)
  2. public class MockBeanTest {
  3. @MockBean
  4. private IUserService userService;
  5. @SuppressWarnings("unchecked")
  6. @Test(expected = NullPointerException.class)
  7. public void testMockBean() {
  8. BDDMockito.given(userService.getUserAge(2L)).willReturn(Integer.valueOf(18));
  9. BDDMockito.given(userService.getUserAge(0L)).willReturn(Integer.valueOf(0));
  10. BDDMockito.given(userService.getUserAge(null)).willThrow(NullPointerException.class);
  11. Assert.assertEquals(Integer.valueOf(18), userService.getUserAge(2L));
  12. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(0L));
  13. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(null));
  14. }
  15. }

Controller测试

在Springboot中可以通过TestRestTemplate和MockMvc来对Controller进行测试,有以下两种情况。

情况一

Controller中未装配任何其他Spring容器中的Bean,例如下面这个控制器。


  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController01 {
  4. @GetMapping("/home")
  5. public String homeUser(@RequestParam(name = "name", required = true) String userName) {
  6. if (null == userName || userName.trim() == "") {
  7. return "you are nobody...";
  8. }
  9. return "This is " + userName + "'s home...";
  10. }
  11. }

此时无需启动Spring容器,可直接使用MockMvc来对Controller进行模拟测试,测试代码如下。


  1. @RunWith(SpringRunner.class)
  2. @WebMvcTest(controllers = { UserController01.class })
  3. public class ControllerTest01 {
  4. @Autowired
  5. private MockMvc mvc;
  6. @Test
  7. public void testAddUser() throws Exception {
  8. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", ""))
  9. .andExpect(MockMvcResultMatchers.status().isOk())
  10. .andExpect(MockMvcResultMatchers.content().string("you are nobody..."));
  11. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", "pengjunlee"))
  12. .andExpect(MockMvcResultMatchers.status().isOk())
  13. .andExpect(MockMvcResultMatchers.content().string("This is pengjunlee's home..."));
  14. }
  15. }

情况二

Controller中需装配其他Spring容器中的Bean,例如下面这个控制器。


  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController02 {
  4. @Autowired
  5. private UserDao userDao;
  6. @GetMapping("/add")
  7. public String addUser(@RequestParam(name = "age", required = false, defaultValue = "0") Integer userAge,
  8. @RequestParam(name = "name", required = true) String userName) {
  9. if (userAge <= 0 || null == userName || userName.trim() == "") {
  10. return "0";
  11. }
  12. userDao.addUser(userAge, userName);
  13. return "1";
  14. }
  15. }

此时除了要启动Spring容器,还需要启动内嵌的WEB环境,有以下两种方法。

方法一

利用TestRestTemplate进行测试。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. public class ControllerTest02 {
  4. @Autowired
  5. private TestRestTemplate template;
  6. @Test
  7. public void testAddUser() {
  8. String result1 = template.getForObject("/user/add?name=pengjunlee", String.class);
  9. Assert.assertEquals("0", result1);
  10. String result2 = template.getForObject("/user/add?age=20&name=Tracy", String.class);
  11. Assert.assertEquals("1", result2);
  12. }
  13. }

方法二

利用MockMvc进行测试。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. @AutoConfigureMockMvc
  4. public class ControllerTest03 {
  5. @Autowired
  6. private MockMvc mvc;
  7. @Test
  8. public void testAddUser() throws Exception {
  9. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("name", ""))
  10. .andExpect(MockMvcResultMatchers.status().isOk())
  11. .andExpect(MockMvcResultMatchers.content().string("0"));
  12. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("age", "22").param("name", "pengjunlee"))
  13. .andExpect(MockMvcResultMatchers.status().isOk())
  14. .andExpect(MockMvcResultMatchers.content().string("1"));
  15. }
  16. }

本文项目源码已上传至CSDN,资源地址:https://download.csdn.net/download/pengjunlee/10394302

原文地址:https://blog.csdn.net/pengjunlee/article/details/80206615

SpringBoot重点详解--使用Junit进行单元测试的更多相关文章

  1. springboot配置详解

    springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...

  2. springboot项目--传入参数校验-----SpringBoot开发详解(五)--Controller接收参数以及参数校验----https://blog.csdn.net/qq_31001665/article/details/71075743

    https://blog.csdn.net/qq_31001665/article/details/71075743 springboot项目--传入参数校验-----SpringBoot开发详解(五 ...

  3. SpringBoot @ConfigurationProperties详解

    文章目录 简介 添加依赖关系 一个简单的例子 属性嵌套 @ConfigurationProperties和@Bean 属性验证 属性转换 自定义Converter SpringBoot @Config ...

  4. Spring Boot2 系列教程 (二) | 第一个 SpringBoot 工程详解

    微信公众号:一个优秀的废人 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 哎呦喂,按照以往的惯例今天周六我的安排应该是待在家学学猫叫啥的.但是今年这种日子就可能一去不复返了,没法办法啊.前 ...

  5. SpringBoot——配置文件详解【五】

    前言 SpringBoot的配置文件 配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的. application.properties application.yml 配置文件 ...

  6. Go语言学习之8 goroutine详解、定时器与单元测试

    主要内容: 1.Goroutine2. Chanel3. 单元测试 1. Goroutine Go 协程(Goroutine)(轻量级的线程,开线程没有数量限制).   (1)进程和线程 A. 进程是 ...

  7. matlab考试重点详解

    此帖是根据期末考试复习重点补充完成, 由于使用word编辑引用图片和链接略有不便, 所以开此贴供复习及学习使用.侵删 复习要点 第一章 Matlab的基本概念,名称的来源,基本功能,帮助的使用方法 1 ...

  8. Springboot 启动详解

    1.前言 最近一直在看Springboot和springcloud代码,看了将近20多天,对这两个系统的认知总算是入了门.后续应该会有一个系列的文章,本文就先从Springboot的启动入手. 2.容 ...

  9. 2.SpringBoot HelloWorld详解

    1.POM文件 父项目 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...

随机推荐

  1. 类库日期和jsp导包

    一.日期类库 1.1. Date Date类创建一个时间,或者是创建一个与你计算机当前的时间:精确到毫秒. //实例化时间类 Date date = new Date(); 1.2.格式转换类 1.2 ...

  2. Linux 、AIX环境下查看oracle配置信息(service_name、SID、tnsname)。

    SID: echo $ORACLE_SID service_name: sqlplus / as sysdba; show parameter instance_name; show paramete ...

  3. bash编程之case语句,函数

    bash脚本编程:之case语句   条件测试: 0: 成功 1-255: 失败   命令: [ expression ] [[ expression ]] test expression   exP ...

  4. c++ 定义一个结构体student,输入多个student的信息并以三种方式显示

    #include <iostream> #include <string> using namespace std; const int slen = 30; struct s ...

  5. 转 WebService两种发布协议--SOAP和REST的区别

    转发文章 https://blog.csdn.net/zl834205311/article/details/62231545?ABstrategy=codes_snippets_optimize_v ...

  6. 【MySQL】mac环境下使用navicat premium连接mysql乱码问题

    ---恢复内容开始--- 最重要的两点:使用navicat premium创建mysql连接和在mysql连接里面创建数据库时,需要注意. 1.创建连接时,Encoding不需要手动选择,保持Auto ...

  7. laravel中使用PHPQuery实现网页采集

    由于没有PHPQuery的composer包安装所以需要我们手动在我们的laravel项目中安装加载PHPQuery,这里需要设置laravel的autoload->class map. 1.首 ...

  8. 【mysql】The server quit without updating PID file

      groupadd mysql useradd -r -g mysql mysql cd /usr/local/mysql chown -R mysql:mysql . scripts/mysql_ ...

  9. 14-15.Yii2.0模型的创建/读取数据使用,框架防止sql注入

    目录 创建数据库 表article 配置 db.php 连接数据库 创建控制器 HomeController.php 创建models 创建数据库 表article 1.创建库表 CREATE TAB ...

  10. Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

    文档:Docker 启动错误.note链接:http://note.youdao.com/noteshare?id=065111d506e1b132dc930dbe88f5d7b0&sub=A ...