单元测试是项目开发中必不可少的一环,在 SpringBoot 的项目中,我们用 @SpringBootTest 注解来标注一个测试类,在测试类中注入这个接口的实现类之后对每个方法进行单独测试。

比如下面这个示例测试类:

  1. @SpringBootTest
  2. public class Tests {
  3. @Test
  4. public void testHello() {
  5. // ...
  6. }
  7. }

但是随着项目的代码量越来越大,你会发现测试类的启动速度变得越来越慢,而大多数情况下只是为了测试一下某个实现类的某个方法而已,比如测试一个DAO类的persist方法。

实际上, @SpringBootTest 注解还提供了两个参数,好好利用这两个参数就可以让测试类的启动速度变得更快。

1.webEnvironment

这个属性决定了测试类要不要启动一个 web 环境,说白了就是要不要启动一个 Tomcat 容器,可选的值为:

  • MOCK, 启动一个模拟的 Servlet 环境,这是默认值
  • RANDOM_PORT,启动一个 Tomcat 容器,并监听一个随机的端口号
  • DEFINED_PORT,启动一个 Tomcat 容器,并监听配置文件中定义的端口(未定义则默认监听8080)
  • NONE,不启动 Tomcat 容器

    只需要通过指定 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 即可达到加速的效果。这时测试类启动时就只会初始化 Spring 上下文,不再启动 Tomcat 容器了!
  1. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
  2. public class Tests {
  3. @Test
  4. public void testHello() {
  5. // ...
  6. }
  7. }

2.classes

classes 属性用来指定运行测试类需要装载的 class 集合,如果不指定,那么会默认装载 @SpringBootConfiguration 注解标注的类。

提到 @SpringBootConfiguration 你可能比较陌生,其实 @SpringBootApplication 的源码里就引入了这个注解:

  1. @Target({ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @SpringBootConfiguration
  6. @EnableAutoConfiguration
  7. @ComponentScan(
  8. excludeFilters = {@Filter(
  9. type = FilterType.CUSTOM,
  10. classes = {TypeExcludeFilter.class}
  11. ), @Filter(
  12. type = FilterType.CUSTOM,
  13. classes = {AutoConfigurationExcludeFilter.class}
  14. )}
  15. )
  16. public @interface SpringBootApplication {
  17. // ...
  18. }

也就是说,如果我们不指定classes属性,那么启动测试类时需要加载的Bean的数量和正常启动一次入口类(即有@SpringBootApplication注解的类)加载的 Bean 数量是一样的。

如果你的项目中有很多个 Bean, 特别是有以下几种时:

  • 有 CommandLineRunner 的实现类
  • 用 @PostConstruct 注解指定了初始化方法的类

启动测试类的时候,就只会加载需要的 Bean 到上下文中,从而加快启动速度。比如:

  1. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes={HelloServiceImpl.class})
  2. public class Tests {
  3. @Test
  4. public void testHello() {
  5. // ...
  6. }
  7. }

即使此时项目中还有另外一个 Bean 在它的初始化方法里写了类似 Thread.sleep(10000) 等操作也不会影响,因为这个 Bean 根本就没有被加载和初始化!

SpringBoot让测试类飞起来的方法的更多相关文章

  1. 创建Car类,包含name,price属性,构造器等方法,创建测试类,在main方法中创建Set接口的实现类,添加5个以上的Car对象,遍历集合元素,验证重复元素是否过滤了; 如果没有过滤,实现过滤功能;把每个小车的price降10000元,再遍历,查看price是否已改变

    i汽车类 package com.lanxi.demo2_3; public class Car { private String name; private int price; @Override ...

  2. IntelliJ IDEA 2017版 SpringBoot测试类编写

    SpringBoot的测试类编写Demo 源码见 https://github.com/liushaoye/baseone.git

  3. JPA实体类注解、springboot测试类、lombok的使用

    前提准备: 搭建一个springboot项目,详情请参见其它博客:点击前往 1 引入相关依赖 web.mysql.jpa.lombok <?xml version="1.0" ...

  4. 学习springboot整合mybatis并编写测试类

    报名立减200元.暑假直降6888. 邀请链接:http://www.jnshu.com/login/1/20535344 邀请码:20535344 遇到的问题: 1.原因是在启动类上只有一个@Map ...

  5. Springboot测试类之@RunWith注解

    @runWith注解作用: --@RunWith就是一个运行器 --@RunWith(JUnit4.class)就是指用JUnit4来运行 --@RunWith(SpringJUnit4ClassRu ...

  6. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  7. Java基础-继承-编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数 wheels和车重weight。小车类Car是Vehicle的子类,其中包含的属性有载人数 loader。卡车类Truck是Car类的子类,其中包含的属性有载重量payload。每个 类都有构造方法和输出相关数据的方法。最后,写一个测试类来测试这些类的功 能。

    #29.编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数 wheels和车重weight.小车类Car是Vehicle的子类,其中包含的属性有载人数 loader.卡车类T ...

  8. XCode中的单元测试:编写测试类和方法(内容意译自苹果官方文档)

    当你在工程中通过测试导航栏添加了一个测试target之后, xcode会在测试导航栏中显示该target所属的测试类和方法. 这一章演示了怎么创建测试类,以及如何编写测试方法. 测试targets, ...

  9. 编写测试类,了解ArrayList的方法

    这篇文章主要介绍了C#中动态数组用法,实例分析了C#中ArrayList实现动态数组的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了C#中动态数组用法.分享给大家供大家参考.具体分析如下 ...

随机推荐

  1. 深入剖析 RocketMQ 源码 - 消息存储模块

    一.简介 RocketMQ 是阿里巴巴开源的分布式消息中间件,它借鉴了 Kafka 实现,支持消息订阅与发布.顺序消息.事务消息.定时消息.消息回溯.死信队列等功能.RocketMQ 架构上主要分为四 ...

  2. Java反射判断对象实例所有属性是否为空

    https://www.jb51.net/article/201647.htm public static Boolean ObjectAllFieldsEmpty(Object obj) throw ...

  3. Spark中的两种模式

    两种模式 client-了解 cluster模式-开发使用 操作 1.需要Yarn集群 2.历史服务器 3.提交任务的的客户端工具-spark-submit命令 4.待提交的spark任务/程序的字节 ...

  4. java-TCP协议发送和接收数据

    TCP协议接收数据的步骤: A:创建接收数据的Socket对象 创建对象的时候要指定端口 B:监听客户端连接 等待客户端连接 C:获取Socket对象的输入流(字节流) D:读数据,并显示在控制台 E ...

  5. [loj3247]Non-Decreasing Subsequences

    分治,考虑分治到[l,r]的区间(设$mid=(l+r)/2$),将询问分为两类:1.在左/右区间,直接递归下去:2.跨越中间,那么处理出两个数组:L[i][j]表示左区间在开头第i个位置,以数字j为 ...

  6. C语言下的Led灯

    1. 设计思想 1.1 设置处理器模式 设置sp啥的汇编要先进入SVC模式,超级管理员特权模式,这样就可以访问所有寄存器了,需要用到cpsr寄存器 0到4位要设置svc模式10011 = 0x13, ...

  7. [IIS]文件夹权限

    发布完iis,默认的 Application Pool 没有权限访问文件夹. 可以给项目文件夹添加用户权限. 右键 - "属性" - "安全" - " ...

  8. 重新整理 .net core 实践篇——— 权限中间件源码阅读[四十六]

    前言 前面介绍了认证中间件,下面看一下授权中间件. 正文 app.UseAuthorization(); 授权中间件是这个,前面我们提及到认证中间件并不会让整个中间件停止. 认证中间件就两个作用,我们 ...

  9. myeclipse激活教程

    1.安装,解压,下一步一下一步,一直到finish..结束 2.汉化破解激活:下载破解压缩包:解压

  10. Atcoder Regular Contest 072 C - Alice in linear land(思维题)

    Atcoder 题面传送门 & 洛谷题面传送门 首先求出 \(s_i\) 表示经过 \(i\) 次操作后机器人会位于什么位置,显然 \(s_0=D\),\(s_i=\min(s_{i-1},| ...