使用Spring Boot隔离集成测试和模拟依赖项

集成测试可能很慢且不可靠,因为它们依赖于系统中过多的组件。 在某种程度上,这是不可避免的:这里的集成测试是为了验证系统的每个部分如何与其他内部或外部组件一起玩。

但是,我们可以通过仅分解所需的依赖关系而不是整个系统来改进某些集成测试。 让我们想象一个依赖于数据库,第三方REST API和消息队列的应用程序:

我的应用程序

现在假设我们希望集成测试验证仅包含对REST API的调用但不包含对数据库或消息队列的调用的行为。 举一个具体的例子,假设我们要检查REST客户端是否正确配置为3秒钟后超时。

为此,我们需要的是一个小型Controller ,该Controller将在返回答案到REST客户端之前等待,以模拟REST API。 等待时间将作为参数传递给查询字符串。

@Profile("restTemplateTimeout")
@RestController
@RequestMapping(value = "/test")
public class DelayedWebServerController {@RequestMapping(value = "/delayRestTemplate", method = GET)public String answerWithDelay(@RequestParam Long waitTimeMs) {if (waitTimeMs > 0) {try {Thread.sleep(waitTimeMs);} catch (InterruptedException e) {throw new RuntimeException(e);}}return "Delayed Result";}}

@Profile批注用于什么? 如果我们将此控制器注入到我们的标准应用程序上下文中,则有几个缺点:

  • 测试将会很慢:我们只需要启动一个控制器,而不是整个控制器
  • 我们的控制器将由Spring拾取并注入其他所有集成测试中,从而减慢每个集成测试的速度,并可能踩到另一个测试的脚趾

更好的选择是启动一个最小的Spring Boot应用程序,仅暴露我们的DelayedWebServerController 。 我们还将告诉Spring Boot仅扫描我们感兴趣的软件包,并排除与持久性相关的自动配置,因为我们不需要它来启动控制器。 这是在类似以下的Configuration类中完成的:

@Profile("restTemplateTimeout")
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@ComponentScan(basePackages = "my.application.resttemplate.timeout")
public class DelayedWebServerConfiguration {//The class is empty and only used to support the annotations
}

Spring上下文配置可能会引起混乱,让我们一个接一个地查看批注:

  • @Profile :这告诉Spring,只有在restTemplateTimeout配置文件处于活动状态时才应使用此配置。 在本文的进一步内容中,我们将看到如何为特定的集成测试启用此配置文件。 正是这个注释防止配置被其他不相关的集成测试所采用。 请注意,我们的DelayedWebServerController具有相同的注释。
  • @Configuration :标准注释,用于告诉Spring这是一个上下文配置类。
  • @EnableAutoConfiguration :在这里,我们禁用了某些不需要进行特定测试的Spring Boot“魔术”
  • @ComponentScan :通过仅扫描一个软件包而不是整个项目,我们可以加快Spring Boot应用程序的启动速度。 Spring不会选择此包之外的任何带有Spring注释的类。

集成测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@WebIntegrationTest("server.port:0")
@SpringApplicationConfiguration(classes = DelayedWebServerConfiguration.class)
@ActiveProfiles("restTemplateTimeout")
public class RestTemplateShould {@Rulepublic ExpectedException thrown = none();@Value("${local.server.port}")private int port;@Autowiredprivate RestTemplate restTemplate;@Testpublic void throw_timeout_if_response_lasts_more_than_two_seconds() {thrown.expect(ResourceAccessException.class);thrown.expectCause(instanceOf(SocketTimeoutException.class));callEndpointWithDelay(3000);}@Testpublic void do_not_throw_timeout_if_response_lasts_less_than_two_seconds() {callEndpointWithDelay(10);}private void callEndpointWithDelay(long delayMs) {restTemplate.getForObject("http://localhost:" + port + "/test/delayRestTemplate?waitTimeMs=" + delayMs, String.class);}
}

当然,所有这些类都存储在我们的测试源文件夹(通常为src/test/java )中,因为生产不需要它们。

让我们再看一下注解:

  • @RunWith :测试将使用Spring Junit运行程序,该运行程序将负责为我们创建Spring上下文。
  • @WebIntegrationTest :告诉Spring这是一个运行Web应用程序的集成测试,否则默认情况下Spring不会在测试模式下运行HTTP服务器。 我们还将server.port的值设置为0以便Spring Boot选择一个随机端口供HTTP服务器监听。 这允许并行运行多个测试,或者在后台运行该应用程序的另一个版本。
  • @SpringApplicationConfiguration :我们告诉Spring在哪里可以找到我们之前创建的DelayedWebServerConfiguration类。
  • @ActiveProfiles :启用restTemplateTimeout配置文件,否则ControllerConfiguration将被过滤掉。

现在,我们有一个集成测试,它以一组有限的依赖关系而不是整个应用程序运行。 如果我们想走得更远并在游戏中添加模拟游戏怎么办? 当依赖项没有开发环境,或者过于复杂而无法从开发人员的工作站调用时,可能需要这样做。 在这种情况下,我们可以将这些模拟添加到Configuration类中,并将它们注入到测试的Spring上下文中。

这是一个Configuration示例,在该示例中,我们注入了一个由Mockito模拟的自定义CustomerService ,而不是默认值:

@Profile("validationTests")
@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@ComponentScan(basePackages = {"my.application.controller","my.application.actions"})
public class ValidationEndToEndConfiguration {@Beanpublic CustomerService customerService() {return Mockito.mock(CustomerService.class);}
}

通过这种方法,我们可以使集成测试更具弹性。 对于缓慢或不可靠的依赖关系,让开发人员针对模拟版本运行集成测试会更加有效。 但是,不要忘记,最终您的应用程序将必须与实际系统集成,而不是与模拟系统集成。 因此,让持续集成服务器至少每天都在真实系统上运行测试是有意义的。

翻译自: https://www.javacodegeeks.com/2016/02/isolating-integration-tests-mocking-dependencies-spring-boot.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS浏览器兼容性问题

CSS浏览器兼容性问题 1、浏览器CSS样式初始化 最简单的初始化方法就是:使用通配符(*),重置所有的初始样式。 *{margin: 0;padding: 0; } /* 10px1rem */ html {overflow-y:scroll;font-size:62.5%; } a{text-decoration:none; …

Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4

说明: 1、使用的Wine版本是深度出品(Deepin),已经精简了很多没用的配置,使启动能非常快,占用资源小。 2、由于Xshell 5的C库无法在这个Wine版本运行,即使升级官方原版的2版本也无法解决&#xf…

字符串反序输出字符串

Console.Write("请输入一个字符串:"); string str Console.ReadLine(); string reverse "";//用于存放反序后的字符串 for (int i str.Length - 1; i > 0; i--) {   reverse str[i]; } Console.WriteLine(reverse":串符字个一入输…

centos8服务器创建新用户并指定该用户只能打开某个目录文件

ssh -V来查看openssh的版本 需求:sftp组,用户mysftp,该用户不能使用ssh,且sftp登录后只能在自己的主目录下操作,不能访问其他目录 1、创建sftp组 groupadd sftp2、创建一个sftp用户,名为mysftp useradd …

[转载]Oracle ltrim() 函数用法

前面有说到过LPAD和RPAD这两个函数用法的文章,今天发现与之相反意义的另外两个函数,那就是LTRIM() RTRIM()。 这次就挑LTRIM() 这一函数来讲讲: 具体的语法格式如下: LTRIM(c1,[,c2]) 【功能】删除左边出现的字符串 【参数】C1 字…

电脑缺失MSVCP110.dll文件

安装某软件显示如下错误。 错误: 原因:电脑缺少MSVCP110.dll系统文件。C:\Windows\System32目录下没有此文件。 解决: 下载vcredist_x64直接双击安装,安装完成后就可以继续安装之前安装不了的软件了。。 这里是我下载的&#…

js正则 匹配 正则表达式

1.由数字、26个英文字母或者下划线组成的字符串: ^[0-9a-zA-Z_]{1,}$2.非负整数(正整数 0 ): ^/d$3.正整数: ^[0-9]*[1-9][0-9]*$4.非正整数(负整数 0): ^((-/d)|(0))$5.负整数 ^-[0-9]*[1-9][0-9]*$6.整数: ^-?…

chromedriver链接

http://npm.taobao.org/mirrors/chromedriver/转载于:https://www.cnblogs.com/shuo1208/p/8023827.html

web csrf java_在Java Web应用程序中阻止CSRF

web csrf java跨站点请求伪造攻击(CSRF)在Web应用程序中非常常见,如果允许,可能会造成重大危害。 如果您从未听说过CSRF,建议您查看有关它的OWASP页面 。 幸运的是,阻止CSRF攻击非常简单,我将向…

MySQL 安全性知识要点

添加、删除用户 1.添加用户 可以使用CREAT USER语法添加一个或多个用户,并设置相应的密码。 语法格式: CREAT USER user [IDENTIFIED BY [PASSWORD] password] [,user [IDENTIFIED BY [PASSWORD] password] ] ... 其中,user的格式为&…

在WildFly的REST Web服务中与Jackson的双向关系

这是使用Jackson的REST Web服务中Java实体之间的双向关系的示例。 假设我们在两个实体Parent和Child之间存在双向关系。 使用MySQL工作台为这两个表生成SQL模式文件。 DROP SCHEMA IF EXISTS bidirectional_schema ; CREATE SCHEMA IF NOT EXISTS bidirectional_schema DEFA…

ICMP Internet控制报文协议

ICMP报文主要有两大功能:查询报文和差错报文。转载于:https://www.cnblogs.com/gardenofhu/p/8027431.html

Postman安装与使用(网络请求神器)--post、get请求

安装 1、Postman最早是作用chrome浏览器插件存在的,所以,你可以到chrome商店搜索下载安装,因为重所周知的原因,所以,大家都会找别人共享的postman插件文件来安装。由于2018年初Chrome停止对Chrome应用程序的支持。 官…

c# 对象 类

类定义中可以使用的访问修饰符组合none or internal 类只能在当前工程中访问public 类可以在任何地方访问abstract or internal abstract 类只能在当前工程中访问,不能实例化,只能继承public abstract 类可以在任何地方访问,不能实例化&#…

openshift用户管理_OpenShift Express Web管理控制台:入门

openshift用户管理本周, 最新版本的OpenShift为已经很棒的PaaS Cloud提供商带来了两个非常好的功能。 首先,JBoss AS已从7.0升级到7.1,并且所有新的Express Web Management Console已作为预览发布。 在本文中,我们将研究如何使用此…

linux系统搭建ftp服务器--只给某个用户访问其默认目录下的文件

1、环境: window操作系统中安装FlashFXP 软件或xftp; 服务器端的操作系统为centos8; 2、检查安装vsftpd软件 查看所有的安装的软件包 并在结果中查找包含vsftp 的文件 rpm -qa | grep vsftpd如果没有装则使用yum命令安装 yum -y install vsftpd3、创…

12月13日 什么是help_method,session的简单理解, find_by等finder method

helper_methodDeclare a controller method as a helper. For example, helper_method :link_todef link_to(name, options) … end makes the link_to controller method available in the view.课程遇到的如current_cart,current_user. 声明后,就可以在view里面使…

Openshift源中的高可用性Drools无状态服务

嗨,大家好! 在这篇博客文章中,我想举一个简单的例子,展示使用Openshift 3(Docker和Kubernetes)扩展Drools Stateless服务有多么容易。 我将展示如何通过按需提供新实例来扩展我们的服务,以及如何…

FTP配置文件详解vsftpd.conf

FTP配置文件详解vsftpd.conf 转载过来做个笔记,原文地址:https://blog.csdn.net/miss520jenny/article/details/92664533 #vi /etc/vsftpd/vsftpd.conf 1.登录和对匿名用户的设置 write_enableYES //是否对登录用户开启写权限。属全局性设…

Visual C++中MFC消息的分类

Visual C中MFC消息的分为三类:标准(窗口)消息、命令消息、控件消息。 1、标准(窗口)消息:窗口消息一般与窗口内部运作有关,如创建窗口,绘制窗口,销毁窗口,通常,消息是从系统发到窗口&#xff0c…