鸡肉和鸡蛋–测试前解决Spring属性

考虑一个负责进行远程调用和获取详细信息的服务类:

 ...  public class CitiesService { private final WebClient.Builder webClientBuilder; private final String baseUrl; public CitiesService( WebClient.Builder webClientBuilder, @Value ( "${cityservice.url}" ) String baseUrl) { "${cityservice.url}" ) String baseUrl) { this .webClientBuilder = webClientBuilder; this .baseUrl = baseUrl; } public Flux<City> getCities() { return this .webClientBuilder.build() .get()  .... 

这是一个Spring Bean,它通过称为“ cityservice.url”的属性来解析要调用的URL。

如果我想测试此类,则在使用WebClient时一直使用的方法是使用出色的Wiremock启动模拟服务器,并使用它来测试此类。 Wiremock模拟看起来像这样:

 private static final WireMockServer WIREMOCK_SERVER = new WireMockServer(wireMockConfig().dynamicPort()); ..... WIREMOCK_SERVER.stubFor(get(urlEqualTo( "/cities" )) .withHeader( "Accept" , equalTo( "application/json" )) .willReturn(aResponse() .withStatus( 200 ) .withHeader( "Content-Type" , "application/json" ) .withBody(resultJson))); 

Wiremock服务器正在一个随机端口上启动,并设置为响应名为“ / cities”的终结点。 这是鸡肉和鸡蛋问题的出处:

1. CitiesService类要求在开始测试之前设置名为“ cityservice.url”的属性。

2. Wiremock在一个随机端口上启动,它响应的URL是“ http:// localhost:randomport”,并且仅在测试开始后才可用。

我可以想到三种可能的解决方案来打破这种循环依赖关系:

方法1:使用硬编码端口

这种方法取决于在固定端口而不是动态端口上启动Wiremock,这样可以在启动测试时设置属性,如下所示:

 @ExtendWith (SpringExtension. class )  @SpringBootTest (classes = CitiesServiceHardcodedPortTest.SpringConfig. class , properties = "cityservice.url= http://localhost:9876 " )  public class CitiesServiceHardcodedPortTest { private static final WireMockServer WIREMOCK_SERVER = new WireMockServer(wireMockConfig().port( 9876 )); 

在此,Wiremock在端口9876上启动,并且启动时的属性设置为“ http:// localhost:9876 /”。

这解决了问题,但是,这不是CI服务器友好的,端口可能在运行时发生冲突,这导致测试不稳定。

方法2:不使用Spring进行测试

更好的方法是不使用这些属性:

 public class CitiesServiceDirectTest { private static final WireMockServer WIREMOCK_SERVER = new WireMockServer(wireMockConfig().dynamicPort()); private CitiesService citiesService; @BeforeEach public void beforeEachTest() { final WebClient.Builder webClientBuilder = WebClient.builder(); this .citiesService = new CitiesService(webClientBuilder, WIREMOCK_SERVER.baseUrl()); } 

在这里,通过在构造函数中显式设置baseUrl来创建服务,从而避免了在测试之前设置属性的需求。

方法3:应用程序上下文初始化器

ApplicationContextInitializer用于以编程方式初始化Spring Application Context,它可与测试一起使用,以在执行实际测试之前注入属性。 遵循以下原则:

 @ExtendWith (SpringExtension. class )  @SpringBootTest (classes = CitiesServiceSpringTest.SpringConfig. class )  @ContextConfiguration (initializers = {CitiesServiceSpringTest.PropertiesInitializer. class })  public class CitiesServiceSpringTest { private static final WireMockServer WIREMOCK_SERVER = new WireMockServer(wireMockConfig().dynamicPort()); @Autowired private CitiesService citiesService; @Test public void testGetCitiesCleanFlow() throws Exception { ... } static class PropertiesInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { TestPropertyValues.of( "cityservice.url=" + " http://localhost: " + WIREMOCK_SERVER.port() ).applyTo(applicationContext.getEnvironment()); } }  } 

首先启动Wiremock,然后使用初始化程序初始化Spring上下文,该初始化程序使用Wiremocks动态端口注入“ cityservice.url”属性,这种属性可用于连接到CityService。

结论

我个人更喜欢方法2,但是最好在测试之前创建Spring的连线和相关的bean,如果类利用了这些,那么我更喜欢方法3。应用程序上下文初始化器提供了一种解决鸡和蛋问题的好方法。这些属性需要在Spring的上下文参与之前提供。

所有代码示例均在此处提供:

方法1:https://github.com/bijukunjummen/reactive-cities-demo/blob/master/src/test/java/samples/geo/service/CitiesServiceHardcodedPortTest.java

方法2:https://github.com/bijukunjummen/reactive-cities-demo/blob/master/src/test/java/samples/geo/service/CitiesServiceDirectTest.java 方法3:https://github.com/bijukunjummen/reactive-cities-demo/blob/master/src/test/java/samples/geo/service/CitiesServiceSpringTest.java

翻译自: https://www.javacodegeeks.com/2019/08/chicken-egg-resolving-spring-properties-ahead-test.html

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

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

相关文章

工业交换机和工控交换机有什么区别?

众所周知&#xff0c;以太网交换机一般分为&#xff1a;商用(以太网)交换机、工业(以太网)交换机、家用(以太网)交换机&#xff0c;因为我们是专业的工业交换机厂家&#xff0c;在这里着重介绍下工业交换机。 工业交换机一般用在工业生产场合&#xff0c;通常外观和安装形式多…

Ubuntu16.04通过wine环境安装微信与QQ等软件

很多双系统用户平时开发项目时会在Ubuntu下进行开发,但是由于Ubuntu下缺少腾讯QQ和微信的官方客户端支持,需要使用微信或者QQ只能使用网页版本,但是有一些用户由于某些原因是无法通过网页登录微信的,会提示"为了你的帐号安全&#xff0c;此微信号不能登录网页微信。你可以…

工业型交换机相比普通交换机有哪些要求?

随着自动化技术逐渐成熟&#xff0c;并伴随工业以太网的应用和大中型工业控制的网络的创建&#xff0c;工业交换机的应用越来越广泛。工业型交换机与一般交换机对比有必须的差异&#xff0c;工业型交换机在整体规划上及其在电子器件的采用上&#xff0c;其抗压强度和可接受性层…

使用eclipse调试ns3配置说明

Tips&#xff1a;安装eclipse时注意选择C开发组件&#xff1b; &#xff08;环境配置参考&#xff1a;https://www.cnblogs.com/zlcxbb/p/3852810.html&#xff09; &#xff08;官方配置介绍&#xff1a;https://www.nsnam.org/wiki/HOWTO_configure_Eclipse_with_ns-3&…

工业以太网交换机特点分析及使用注意事项

在网络发达的今天&#xff0c;交换机被许多需要使用网络的朋友使用&#xff0c;可以实现一个网络多台电脑公用。但是什么是工业以太网交换机&#xff0c;很惯性的思维就是工业用的交换机&#xff0c;但是具体工业以太网交换机性能特点有什么呢&#xff1f;接下来就由杭州飞畅科…

java整数的因式分解_如何在Java中找到整数的质数-因式分解

java整数的因式分解编程课程中的常见家庭作业/任务之一是关于Prime Factorization。 要求您编写一个程序以找到给定整数的素因子 。 一个数字的素数因子是将精确地除以给定数字的所有素数。 例如&#xff0c;素数因子35是7和5&#xff0c;它们本身都是素数&#xff0c;并且精确…

【最新】解决Github网页上图片显示失败的问题

转载链接&#xff1a; https://blog.csdn.net/qq_38232598/article/details/91346392?utm_mediumdistribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai&depth_1-utm_sourcedistribute.pc_relevant_t0.none-task-blog-BlogCommend…

串口服务器的通讯模式

串口服务器&#xff0c;一个为RS-232/485/422到PC/IP之间完成数据转换的具有强大功能的方便快捷的通讯接口转换器。串口服务器通过作为服务器端&#xff0c;提供RS-232/485/422终端串口与TCP/IP网络的数据双向透明传输&#xff0c;提供串口转网络功能&#xff0c;RS-232/485/42…

JUnit 5和Selenium –使用Gradle,JUnit 5和Jupiter Selenium设置项目

Selenium是一组支持浏览器自动化的工具和库&#xff0c;主要用于Web应用程序测试。 Selenium的组件之一是Selenium WebDriver&#xff0c;它提供客户端库&#xff0c;JSON有线协议&#xff08;与浏览器驱动程序进行通信的协议&#xff09;和浏览器驱动程序。 Selenium WebDrive…

机器学习相关知识 大佬博客整理

一 马尔科夫链详细介绍 https://www.cnblogs.com/traditional/p/12612010.html

ns3gym与ns3ai的安装方法

编译运行的常用命令 1&#xff0c;针对ns3主项目的编译命令 分两步&#xff1a;第一&#xff0c;./waf configure&#xff1b;第二&#xff0c;./waf&#xff08;或者./waf build&#xff09; 详见《开源网络模拟器ns3》P13 2&#xff0c;针对多脚本同时运行的编译命令 ns3…

Ubuntu16.04安装WPS

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循<a href"http://creativecommons.org/licenses/by-sa/4.0/" target"_blank" rel"noopener"> CC 4.0 BY-SA </a>版权协议&#xff0c;转载请附上原文出处链接和本声明。 原文…

网络仿真中数据生成相关

1 流量激励生成 十分钟泊松分布 了解泊松分布与指数分布的关系

apache hadoop_通过Apache Hadoop大规模扩展Apache Solr实时实时索引

apache hadoop播客的第22集是与Patrick Hunt的谈话 我们讨论了Apache Solr&#xff08;上游&#xff09;中的新工作&#xff0c;使它可以在Apache Hadoop上工作。 Solr支持将其索引和事务日志文件写入和读取到HDFS分布式文件系统。 这不使用Hadoop Map-Reduce处理Solr数据&…

显示/隐藏我的电脑与回收站

Windows徽标键i”——打开——“Windows设置”——点击——“个性化”——进入——“主题”——下滑——“相关设置”——中的——“桌面图标设置”。把勾勾全去掉即可。

没有Javax的Jakarta EE:这次世界也不会结束

如果您错过了新闻&#xff0c; Oracle将向Eclipse基金会捐赠Java EE规范 。 这项决策在规范过程中经历了相当长时间的休眠&#xff0c;在此过程中&#xff0c;人们理所当然地怀疑Oracle对Java EE失去了战略兴趣。 起初&#xff0c;Java EE和更广泛的Java社区很好地满足了捐赠规…

NS3Gym python侧代码分析

argparse库参考链接: https://docs.python.org/zh-cn/3/howto/argparse.html

火狐浏览器常用操作

1 建立书签文件夹并在标签栏显示 https://zhidao.baidu.com/question/1510197150305270220.html

pat乙级 1007 素数对猜想(C++)

题目 让我们定义dn为&#xff1a;dn pn1 −pn &#xff0c;其中p​i​​ 是第i个素数。显然有d​1​​ 1&#xff0c;且对于n>1有d​n​​ 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。现给定任意正整数N(<105 )&#xff0c;请计算不超过N的满足猜想…

如何在不增加人员的情况下自动化API安全程序

在这篇文章中&#xff0c;我们将撰写一篇综合文章&#xff0c;内容涉及如何在不增加人员的情况下自动执行API安全程序。 在现代世界中&#xff0c;数据对于提供者和消费者都至关重要。 数据科学的出现证明了这一事实。 对于某些组织&#xff0c;整个业务模型是建立在信息交换之…