不得不说,测试真的是太重要了!但并不是所有的开发者都这样认为,这种感觉在我回到洛阳后尤其强烈。竟然有团队成员不经测试就把代码提交到代码库,并且是会报错的那种,我天呐,遇到这种队友我也是醉了。

我之前是在一家日企工作,他们非常注重测试,占用的时间比代码编写的时间多多了。从单元测试到集成测试,所有的测试结果都要整理成文档保存下来,哪怕你觉得完全没有必要。但正是这种一丝不苟的态度,成就了日企软件高质量的美誉。

单元测试通常比较简单,对运行环境的依赖性不强。但集成测试就完全不同了,需要整个项目是能够跑起来的,比如说需要数据库是连接的,网络是通畅的等等。

集成测试最简单的形式是:把两个已经测试过的单元组合成一个组件,测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合为程序的更大部分。方法是测试片段的组合,并最终扩展成进程,将模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。

Spring 提供了 Spring TestContex Framework 来支持集成测试,它不依赖于特定的测试框架,因此你可以选择 Junit,也可以选择 TestNG。本文选择 Junit,因此需要先将 Junit 和 Spring TestContex Framework 的依赖添加到 pom.xml 文件中。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.2.RELEASE</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

准备工作完成后,来考虑这样一个场景,我们需要同时为开发环境和生产环境维护数据源配置,因此我们先创建一个公共的接口 Datasource,内容如下所示:

public interface Datasource {
    public void setup();
}

新建 DevDatasource 类,实现 Datasource 接口,该类用于为开发环境配置数据源,内容如下:

@Component
@Profile("dev")
public class DevDatasource implements Datasource {
    @Override
    public void setup() {
        System.out.println("开发环境");
    }
}

@Component 注解用于为 Spring 容器注入一个通用的 Bean 组件。@Profile 注解用于标识不同环境下要实例化的 Bean,字符串“dev” 表示该组件用于开发环境。

新建 ProdDatasource 类,实现 Datasource 接口,该类用于为正式运行环境配置数据源,内容如下:

@Component
@Profile("prod")
public class ProdDatasource implements Datasource {
    @Override
    public void setup() {
        System.out.println("正式环境");
    }
}

新建配置类 SpringTestConfig,内容如下:

@Configuration
@ComponentScan("test")
public class SpringTestConfig {
}

@Configuration 注解表示当前类为一个配置类,@ComponentScan 注解用于指定扫描路径,该路径下的 Bean 将会自动装配到 Spring 容器中。

基于 Maven 构建的项目默认有两个测试目录,src/test/java 和 src/test/resources,分别对应于 src/main/java 和 src/main/resources。前者用于测试项目源码,后者用于测试项目资源。

我们在 src/test/java 目录下新建测试类 DevTest,内容如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("dev")
@ContextConfiguration(classes = { SpringTestConfig.class })
public class DevTest {
    @Autowired
    Datasource datasource;

    @Test
    public void testSpringProfiles() {
        Assert.assertTrue(datasource instanceof DevDatasource);
    }
}

1)@RunWith 注解用于指定 Junit 运行环境,是 Junit 提供给其他框架测试环境的接口扩展,Spring 提供了 org.springframework.test.context.junit4.SpringJUnit4ClassRunner 作为 Junit 测试环境。

2)@ActiveProfile 注解用于指定哪个配置文件处于活动状态,本例为开发环境“dev”。

3)@ContextConfiguration 注解用于指定配置类,本例为 SpringTestConfig 类。

4)@Autowired 注解用于指定 Spring 要自动装配的 Bean。

5)@Test 注解用于表示当前方法为 Junit 测试方法。

程序运行的结果如下图所示:


再新建一个测试类 ProdTest,内容如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("prod")
@ContextConfiguration(classes = { SpringTestConfig.class })
public class ProdTest {

    @Autowired
    Datasource datasource;

    @Autowired
    Environment environment;

    @Test
    public void testSpringProfiles() {
        for (String profileName : environment.getActiveProfiles()) {
            System.out.println("当前激活的 profile - " + profileName);
        }
        Assert.assertTrue(datasource instanceof ProdDatasource);
    }
}

这次使用 @ActiveProfiles("prod") 注解指定当前环境为正式运行下的环境。本例中我们装配了一个新的 Bean environment,使用它的 getActiveProfiles() 方法可以获取当前激活的 Profile。程序运行的结果如下图所示:


好了,我亲爱的读者朋友,以上就是本文的全部内容了,是不是感觉在 Spring 中进行集成测试还是挺简单的?如果觉得文章对你有点帮助,请微信搜索「 沉默王二 」第一时间阅读。示例代码已经上传到 GitHub,传送门~

我是沉默王二,一枚有趣的程序员。原创不易,莫要白票,请你为本文点个赞吧,这将是我写作更多优质文章的最强动力。

一文教会你如何在 Spring 中进行集成测试,太赞了的更多相关文章

  1. 6.1 如何在spring中自定义xml标签

    dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...

  2. 如何在spring中运行多个schedulers quartz 实例

    http://wzping.iteye.com/blog/468263 1.定义一个JOB <!-- 使用pojo来做job,指定pojo和method -->     <bean ...

  3. 如何在 spring 中启动注解装配?

    默认情况下,Spring 容器中未打开注解装配.因此,要使用基于注解装配,我们 必须通过配置 <context:annotation-config/> 元素在 Spring 配置文件 中启 ...

  4. 如何在spring中获取request对象

    1.通过注解获取(很简单,推荐): public class Hello {@Autowired  HttpServletRequest request; //这里可以获取到request} 2.在w ...

  5. (转)Spring中@Async用法总结

     原文:http://blog.csdn.net/blueheart20/article/details/44648667 引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的: ...

  6. Spring中@Async用法总结

    引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3. ...

  7. 玩转Spring MVC(五)----在spring中整合log4j

    在前边的基础上,本文主要总结一下如何在spring 中配置log4j,在本文末尾会给出完整项目的链接. 首先是web.xml中要新添加的代码: <!-- 6. 配置log4j --> &l ...

  8. Spring中@Async

    在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后, ...

  9. Spring中的@Async

    在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3.x之后, ...

随机推荐

  1. TCP报文首部

    源端口和目的端口,各占2个字节,每个TCP报文段都包含源端口号和目的端口号,用于寻找发送端和接收端的应用进程: 序号,占4个字节,序号用来标识从TCP发送端向TCP接收端发送的数据字节流,它表示在这个 ...

  2. C++ 标准模板库(STL)-string

    总结了一些c++ string库常用的库函数用法 #include <iostream> #include <string>//string类可以自动管理内存 using na ...

  3. 苹果笔记本 安装 ubuntu 默认没有无线网卡 的 解决方案

    sudo apt-get update sudo apt-get install bcmwl-kernel-source

  4. Python基础篇(四)_组合数据类型的基本概念

    Python基础篇——组合数据类型的基本概念 集合类型:元素的集合,元素之间无序 序列类型:是一个元素向量,元素之间存在先后关系,通过序号进行访问,没有排他性,具体包括字符串类型.元组类型.列表类型 ...

  5. Deepin中安装使用好用的字典GoldenDict

    2020-03-21   23:08:17 不说废话直接来安装步骤: 打开Deepin的应用商店,输入GoldenDict查找: 找到后点击安装,然后等待一小会,电脑提示音告诉你已经安装完成: 然后再 ...

  6. 基于.NetCore3.1搭建项目系列 —— 使用Swagger做Api文档 (下篇)

    前言 回顾上一篇文章<使用Swagger做Api文档 >,文中介绍了在.net core 3.1中,利用Swagger轻量级框架,如何引入程序包,配置服务,注册中间件,一步一步的实现,最终 ...

  7. python函数版ATM

    最近系统的学习python函数知识点,感觉在面向对象之前,函数的功能确实强大. 最近使用函数写了ATM项目,虽然需求简单但也有很多知识点需要注意,这个项目把python基础的很多知识点都用上了. 前前 ...

  8. Linux---使用kill杀不掉进程解决方案

    今天打开Linux虚拟机,然后使用jps命令查看,莫名奇妙多了一个1889进程 然后使用kill杀掉后,再运行jps还是存在此进程.于是乎开始大量百度,最终找到了解决方案. 说的很清楚了,杀不掉的原因 ...

  9. Hive支持的文件格式和压缩格式及各自特点

    Hive中的文件格式 1-TEXTFILE 文本格式,Hive的默认格式,数据不压缩,磁盘开销大.数据解析开销大. 对应的hive API为:org.apache.hadoop.mapred.Text ...

  10. 大型Java进阶专题(五) 设计模式之单例模式与原型模式

    前言 ​ 今天开始我们专题的第四课了,最近公司项目忙,没时间写,今天抽空继续.上篇文章对工厂模式进行了详细的讲解,想必大家对设计模式合理运用的好处深有感触.本章节将介绍:单例模式与原型模式.本章节参考 ...