【Maven】本地执行一个模块的UT失败,但是线上能执行成功

2023-10-12 16:52

本文主要是介绍【Maven】本地执行一个模块的UT失败,但是线上能执行成功,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

在一个工程项目中,往往我们都需要针对新写的代码补充 UT.
基于此,我们每次进一次新的代码,比较好的习惯就是用新的 UT 去覆盖或者旧的UT 去覆盖掉当前新写的 代码。

而就在最近,发现有 UT 不管在本地清理缓存之后,依旧执行失败,但是在线上却都能每次都成功。
并且两边的 UT 执行都是串行的,所以可以很确定的说,这个 UT 肯定在本地有上下文影响的。

原因定位

串行执行,但是顺序不一样?

在确定了串行执行的之后,发现,既然都是串行的,线上和本地的电脑执行的 maven 版本也都对齐了都情况下。

对齐 maven 版本,是为了避免再次遇到奇奇怪怪的问题,在定位问题的时候,如果没有太多的上下文,那么对齐测试步骤和使用工具版本是非常有必要的。

理论上,两边的执行case 的顺序也应该是一样的。
但是很不幸,使用脚本快速确认两边执行的测试用例的顺序是不一样。
预期失败的 case 是在本地最后一个执行的,而在线上 却是在中间就执行了。

万幸的是,确定了顺序是不一样,那么就很快确定,其实影响了case 范围我们也能确定下来。

排除了线上能执行通过的前置的那些case,那么剩下的case 肯定就是能影响到了。

到底是哪个case 影响到了?

确定了影响的范围的 case 到底是哪些呢?是一个还是两个?

一个简单的做法其实就是二分法,将剩下的 影响的case 一半 disable或者说是skip 掉,然后重跑,逐渐缩小其范围,当然我们可以写脚本去触发 ut 执行即可。

最终,确定了影响的case 竟然是这样写代码!

@Test
public void testA() {...MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class));utilities.when(StaticUtils::name).thenReturn("Eugen");assertThat(StaticUtils.name()).isEqualTo("Eugen")...
}

有小伙伴看出是什么问题了吗?!

对,乍一看好像什么都没错,但是实际上这个是有大问题的!

因为根据 Maven 官方一些使用文档,着重提醒了如下内容!
参考文档:
maven 使用手册:关于 static mocks
Mocking Static Methods With Mockito

As previously mentioned, since Mockito 3.4.0, we can use the Mockito.mockStatic(Class classToMock) method to mock invocations to static method calls. This method returns a MockedStatic object for our type, which is a scoped mock object.

Therefore, in our unit test above, the utilities variable represents a mock with a thread-local explicit scope. It’s important to note that scoped mocks must be closed by the entity that activates the mock. This is why we define our mock within a try-with-resources construct so that the mock is closed automatically when we finish with our scoped block.

意思简单翻译下就是:如果要用 mock static 那么请注意使用 try-with-resources 的方式,不要让其影响到整个测试流程!

@Test
public void testA() {...try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class))) {utilities.when(StaticUtils::name).thenReturn("Eugen");assertThat(StaticUtils.name()).isEqualTo("Eugen")}...
}

总结

这个 mock static 影响的非常大,但是藏着又特别深,在非常多的 case 当中去找到影响的 case 是非常费力又不讨好的事情。
所以,千万谨记,如果要用相关的 测试方式,请查看人家的官网测试手册给到的建议!!!

番外

为什么线上的 maven 和 本地的maven 的执行 ut case 顺序不一样?
原因在于,线上的执行命令修改了,并且用的排序方式是使用执行测试的方法名字典序排列。
而本地执行顺序是以执行方法类的字典序排列。
这就是一开始的差异点。

这篇关于【Maven】本地执行一个模块的UT失败,但是线上能执行成功的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/197183

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

Maven(插件配置和生命周期的绑定)

1.这篇文章很好,介绍的maven插件的。 2.maven的source插件为例,可以把源代码打成包。 Goals Overview就可以查看该插件下面所有的目标。 这里我们要使用的是source:jar-no-fork。 3.查看source插件的example,然后配置到riil-collect.xml中。  <build>   <plugins>    <pl

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们