在一些企业的实践中,要求开发人员编写测试编码来测试业务逻辑,以提高编码的质量、降低错误的发生概率以及进行性能测试等。这些IDE在创建Spring Boot应用的时候已经引入了测试包,只需要看到pom.xml就可以看到的内容:

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

spring-boot-starter-test 会引入JUnit的测试包,这也是现实中使用得最多的方案,所以下面基于它进行讨论 。在Spring Boot可以支持多种方面的测试 , 如 JPA、 MongoDB、 REST风格和Redis 等。基于实用原则,这里主要讲解测试业务层类、 REST风格和 Mock 测试。

1.构建测试类

在创建Spring Boot项目的时候,IDE会同时构建测试环境 ,这一步不需要自己处理。这里看到IDE 自动创建的测试包(test),下面会包含一个可运行测试的文件,如下:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;/*** @author TaoistQu*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests {@Testpublic void contextLoads() {}
}

这里的contextLoads是一个空的逻辑,其中注解@RunWith所载入的类SpringRunner是Spring结合JUnit的运行器,所以这里可以进行JUnit测试。注解@SpringBootTest是可以配置Spring Boot的关于测试的相关功能。上述的contextLoads是一个空实现,下面举例说明如何进行测试。下面假设已经开发好了UserService接口的Spring Bean,并且这个接口提供了getUser方法来获取用户信息。基于这个假设,测试代码如代码如下所示:

import cn.test.pojo.User;
import cn.test.service.UserService;
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;/*** @author TaoistQu*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests {//注入用户服务类@Autowiredprivate UserService userService;@Testpublic void contextLoads() {User user = userService.getUser(2);Assert.assertNotNull(user);System.out.println(user);}}

代码中UserService可以直接从IoC容器中注入,无须再进行任何处理。而在方法中使用了断言来判断用户是否为空,这便是最为主要的测试方式。但并不是所有的方法都能很好地进行测试,例如之前谈到的RestTemplate调用其他的微服务得到的数据,可能在进行测试之时,该微服务因为特殊原因没有开发完成,无法为当前项目提供测试数据,导致正常的测试无法进行。这时Spring还会给予更多的支持,作为辅助去消除这些因素给测试带来的影响。

2.使用随机端口和REST风格测试

有时候,本机已经启动了8080端口,这时进行测试会就会占用这个端口。为了克服这个问题,在Spring Boot中提供了随机端口的机制。这里假设一个基于REST风格的请求

GET /user/get_user/{id}

已经开发好了,而且本地已经开启8080端口服务。这里就可以使用随机端口进行测试了,如下代码所示:

import cn.tpson.test.pojo.User;
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.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;/*** @author TaoistQu*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class TestApplicationTests {@AutowiredTestRestTemplate restTemplate;@Testpublic void getUser() {User user = restTemplate.getForObject("/user/get_user/{id}", User.class, 1);Assert.assertNotNull(user);System.out.println(user);}
}

首先这里配置了注解@SpringBootTest的配置项webEnvironment为随机端口启动,这样在运行测试的时候就会使用随机端口启动。其次注入了REST测试模板(TestRestTemplate),它是由Spring Boot的机制自动生成的,它的使用方法在第11章中已经阐述,所以这里就不再赘述它的使用方法。在testGetUser方法中,标注了@Test,说明它是JUnit的测试方法之一,其逻辑是测试REST风格的请求(获取用户)。通过这些就能够对控制器的逻辑也进行测试。

3.Mock测试

假设当前服务主要是提供用户方面的功能,有时候还希望查看用户购买了哪些产品以及产品的详情,而产品的详情是产品微服务提供的。这时,当前服务就希望通过一个产品服务接口(ProductService),基于REST风格调用产品微服务来获取产品的信息。然而当前的产品微服务还未能提供相关的功能,因此当前的测试不能继续进行。这时,Mock测试的理念就到来了。Mock测试是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。简单地说,如果产品服务接口(ProductService)的getProduct方法当前无法调度产品微服务,那么Mock测试就可以给一个虚拟的产品,让当前测试能够继续。下面举例说明。这里假设需要获取一个产品的信息,然后产品微服务还没有能提供相关的功能。这时希望能够构建一个虚拟的产品结果来让其他的测试流程能够继续下去。下面用如代码清单16-9所示的代码来模拟这个场景。

import cn.test.pojo.Product;
import cn.test.service.ProductService;
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;/*** @author TaoistQu*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class TestApplicationTests {@MockBeanprivate ProductService mockService;@Testpublic void testMock() {Product mockProduct = new Product();mockProduct.setId(1);mockProduct.setName("TaoistQu");BDDMockito.given(mockService.getProduct(1)).willReturn(mockProduct);Product product = mockService.getProduct(1);System.out.println(product);Assert.assertTrue(product.getId() == 1);}
}

代码中注解@MockBean代表对哪个Spring Bean使用Mock测试。所以在测试方法testGetProduct中,先是构建虚拟对象,因为按假设ProductService并不能提供服务,所以就只能先模拟产品(mockProduct)。模拟对象后,使用Spring Boot引入的Mockito来指定Mock Bean、方法和参数,并指定返回的虚拟对象。这样当进行测试产品服务(ProductService)时,在调用getProduct方法且参数为1的情况下,它就会返回之前构建的虚拟对象。调试结果:

参考书目:

  • 《SpringBoot In Action》-【美】 Craig Walls
  • 《深入浅出Spring Boot 2.x》–杨开振

SpringBoot集成JUnit测试相关推荐

  1. springboot集成Junit在执行测试类的时候提示Failed to resolve异常

    项目场景:springboot集成Junit在执行测试类的时候提示Failed to resolve异常 项目场景:springboot版本2.5.7,Junit版本:4.13.2,在执行测试类的时候 ...

  2. springboot集成swagger2测试接口

    springboot集成swagger2测试接口 1.需要的依赖 2.开始编写一个swagger2 3.演示效果图片 1.需要的依赖 <dependency><groupId> ...

  3. SpringBoot整合Junit测试

    文章目录 SpringBoot整合Junit测试 1.SpringBoot引入springboot的测试依赖 2.生成测试方法 3.测试结果 SpringBoot整合Junit测试 假设已对mybat ...

  4. SpringBoot整合junit测试案例

    1.之前开发项目是不要求写单测的,最近公司管理严格需要对开发的功能编写单测,所以在此记录下springboot对junit的整合以及使用的方式 2.引入需要用到的依赖jar包,一般创建好springb ...

  5. SpringBoot使用junit测试

    一.引入maven依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId& ...

  6. SpringBoot中使用Junit测试

    文章目录 SpringBoot整合Junit测试 目录 1.SpringBoot引入springboot的测试依赖 2.生成测试方法 3.测试结果 SpringBoot整合Junit测试 假设已对my ...

  7. SpringBoot集成Maven工程

    1.说明 通过Maven向导创建一个Maven Project, 而非Spring Boot向导创建Spring Starter Project, 然后通过手工修改的方式, 使这个Maven工程支持S ...

  8. SpringBoot——SpringBoot集成Swagger生成API文档

    文章目录: 1.写在前面 2.步骤详解 2.1 pom文件中添加Swagger依赖 2.2 在application.properties核心配置文件中配置Swagger 2.3 编写需要生成API文 ...

  9. SpringBoot笔记:SpringBoot集成JWT实战

    文章目录 JWT 简介 概念 JWT 的认证流程 优缺点 JWT 消息构成 header playload signature SpringBoot 集成 JWT 实战 maven 依赖 JwtUti ...

最新文章

  1. python的基本知识点
  2. css画横线箭头_用CSS绘制三角形箭头
  3. Docker技术实践——中级篇
  4. python @修饰符_Python基础(面向对象之类成员与修饰符)
  5. Python 列表复制
  6. 2021.4.23最新mac11.1 big sur 关于CocoaPods安装和使用
  7. python flask源码解析_浅谈flask源码之请求过程
  8. 开源特训营 - Lesson 6 - 如何提交一个合格的PR
  9. Java Object类的各个方法
  10. AJAX异步检查,检查用户名是否存在
  11. 马斯克2021五大预测:重返月球并比赛遥控汽车,全面实现自动驾驶,你pick哪一个?...
  12. 数据库工作笔记017---还记得Oracle悲观锁和乐观锁嘛?以及hibernate对乐观悲观锁的封装
  13. MyBatis入门到精通——Mybatis入门篇
  14. mysql strchr_PHP字符串函数之 strstr stristr
  15. spss之数据预处理
  16. 《数学之友》期刊简介及投稿要求
  17. matlab仿真光学拍,MATLAB光学干涉实验的仿真研究
  18. 华盛顿州法律确定区块链记录具有法律效力和可执行性
  19. PHP 开发者应了解的 24 个库
  20. 团队作业8----第二次项目冲刺(Beta阶段) 第三天

热门文章

  1. 每天学习八小时以下是不道德的(牛人的语言学习历程)--转
  2. 2-初学测开-环境治理-pipenv的安装和使用
  3. 有着许多强大功能的迅捷CAD看图软件
  4. Ubuntu16.04+python2.7搭建opencv3.2.0
  5. kubernetes实战篇之Dashboard的访问权限限制
  6. 计算机中的标准用户不见了,Win7系统计算机管理本地用户和组不见了怎么找回...
  7. 如何知道哪些表是FTS
  8. 微信小程序代码修改无效
  9. 哥德尔(Kurt Godel)的预言实现了
  10. R语言组合绘图和多个图形叠加、图片叠加绘图