@MockBean 危害

news/2024/6/29 6:21:14 标签: java, 数据库, 大数据

号外!号外!号外!你的 spring boot integration tests 运行慢吗,是不是每跑一次测试,你都在等待,等待它全绿的那一瞬间。如果你遇到,那请接着往下看,也许可以帮助到你。如果你没有遇到,那也请往下看,因为也许以后你会遇到。

告诉你一个秘密:@MockBean会导致测试类(Test Class)之间spring boot application context不断启动多次!!!

不信,那么我们请看栗子 MockBean Annotation:

这项目有两个测试类,AboutControllerTest 和 TokenControllerTest

AccountControllerTest:

AccountControllerTest

TokenControllerTest:

TokenControllerTest

AccountControllerTest 没有使用 @MockBeanTokenControllerTest 使用 @MockBean。下面是两个测试一起运行产生的日志:

spring boot log

如上图所示,spring boot 启动两次。而spring boot 的启动时间也比较耗时,所以@MockBean,很有可能导致测试运行的很慢。那@MockBean到底是个怎么样的存在?

WHAT

写过spring boot integration test的小伙伴,对于@MockBean应该会比较熟悉。在写测试时,对于一些应用的外部依赖需要进行一些Mock 处理,比如:RedisElasticSearchExternalService 等。官方文档介绍 Mocking and spying beans:

mock bean

  • It allows to add Mockito mocks in a Spring ApplicationContext.
  • If a bean, compatible with the declared class exists in the context, it replaces it by the mock.
  • If it is not the case, it adds the mock in the context as a bean.

也就是说,@MockBean会改变spring boot application context beans,导致使用了@MockBean的测试类之间的需要不同application context,从而导致spring boot application context重启。为什么需要不同application context 就需要重启???带着疑惑,我们接着往下看。

WHY

Spring Boot Application Context

什么是application context?简单理解,就是应用程序运行所需要的上下文。官方文档介绍 Context Management:

context management

官方文档介绍 Context management and caching:

testing-ctx-management

根据官方文档意思,application context为初始化测试实例提供上下文,如果需要不同的application context实例化不同的测试,就需要重新启动spring boot,创建不同applicaiton context。文档还说到,为了解决spring boot application context启动慢的问题,会做缓存处理。那@MockBean到底破坏了什么样的缓存规则,从而导致spring boot重启多次?是什么导致打开方式出了问题?

Spring Boot Application Context Cache

要回答这个问题,就要先了解application context cachinguniquely key包含的内容,附上官方文档介绍 Context caching:

Context Caching

根据文档的描述,不难知道application context cacheing是通过key:value方式进行缓存的,唯一键为组合键,包含:locations、classes、contextInitializerClasses、contextCustomizers、contextLoader、parent、activeProfiles、propertySourceLocations、propertySourceProperties、resourceBasePath

@MockBean的使用会导致每个application contextcontextCustomizer的不同,从而导致存储在context cache中的application contextuniquely key不同,最终导致application context在测试类之间不能共享。虽然没有官方文档说明这一点,不过在
org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory 源代码中可以找到一些痕迹:

MockitoContextCustomizerFactory

图中所说的MergedContextConfiguration就是application context cachinguniquely key

HOW

对于spring boot integration test 来说,除了 external service(clients...) 需要被 Mock,其它的内部依赖(service、repository…)都不应该被Mockexternal service 可以在配置层,进行Mock,然后在测试类中,直接通过@Auotwrite方式注入:

RedisTemplateBeanConfigurationMocker:

redis configuration mocker

RedisConfiguration:

redis configuration

TokenControllerTest:

token controller fixed

TokenControllerTest,直接 @Autowrite RedisTemplateBeanConfigurationMocker 中配置的,RedisTemplate @Bean。完成栗子,请查mockbean-annotation。

写在最后

spring boot integration test 相对于 api test,应该更关注api功能的完整性,了解依赖的边界,不需要Mock的,就不要Mock,比如:service, repository…。对于外部依赖,统一在配置层完成 Mock,比如:client、redis、rabbitmq...

原文链接

http://www.niftyadmin.cn/n/1669479.html

相关文章

oracle中日期怎么写,在oracle 裡面日期常用格式的寫法

有天有人問我他需要知道oracle 裡面的sysdate 但是只需要知道日期就行了,當時第一反映就是從dual 裡面查找然後轉化格式就可以了,其實的確是這樣的,不過今天做個總結:[more]日期的各部分的常用的的寫法 1>.取時間點的年份的寫法: SELECT TO_CHAR(SYSDATE,YYYY) FROM DUAL; 2…

oracle中怎么将表中数据存储在内存中,将oracle中常用的表固定在内存中

(1)查看表的存放地点,默认存放到default中SQL> selecttable_name,tablespace_name,blocks,buffer_pool from dba_tables whereownerSCOTT;TABLE_NAME TABLESPACE BLOCKS BUFFER_---------- -------------------- -------DEPT SYSTEM 1 DE…

No10.精选前端面试题,享受每天的挑战和学习

文章目录 Linux 中五种 IO 模型四次挥手之后为什么还要等待 2mslcookie 和 session 的区别是什么tcp 怎么保证可靠性css实现图片自适应宽高的几种方法 Linux 中五种 IO 模型 在 Linux 中,常见的五种 I/O(Input/Output)模型包括: …

junger oracle,My Farewell Party in PartyWorld

时间:2009年1月15日 6:00pm - 10:00 pm地点:钱柜朝阳门店缘由:践行 Team新年派对1. 林乐(Arthur)沈阳人 中科大计算机硕士 Dev - OCEP Developer我最欣赏的帅哥。睿智、幽默、爱好广泛。跟我关系最好,也是最谈得来的2. 周小超(Te…

ExtJS4 根据分配不同的树形菜单在不同的角色登录后

继续我的最后。建立cookie后,带他们出去 var userName Ext.util.Cookies.get(userName); var userAuthority Ext.util.Cookies.get(userAuthority);//0,1,2接下来就能够用了 //树形菜单依据不同权限显示 var treeUrl../store/ccTreeuserAuthority.json;var treeS…

Egret之Visual Studio Code环境配置

一 : 为VSC安装插件 , 一共为2个 1 是Chrome插件 , 2 Egret插件具体步骤①:②:③: 二 : 配置 launch.json / tasks.json 1 按 F5 选择 Chrome , 可以生成 launch.json 2 配置launch.json①,加入配置: {"name": "使用本机 Chrome 调试","type": &…

七个人生工具:SWOT、PDCA、6W2H、SMART、WBS、时间管理、二八原则

为什么80%的码农都做不了架构师?>>> 一、SWOT分析法: Strengths:优势 Weaknesses:劣势 Opportunities:机会 Threats:威胁 意义:帮您清晰地把握全局,分析自己在资源方面的…

oracle安装中出现03111,oracle错误一览.doc

oracle错误一览oracle错误一览ORA-03001: 未执行的特性orA-03002: 未执行的运算符orA-03007: 废弃的特性orA- 03008: 参数 COMPATIBLE > 需要orA-03100: 无法分配通信区域;内存不足orA- 03105: 内部协议错误orA-03106: 致命的双工通信协议错误orA-03107: oranet …