谨慎使用 @MockBean注解
目录
- 问题定位
- 参考issue
- 文档释义
- 解决方案
- 快速方案
- 相关阅读
- 其他资料
问题定位
@MockBean或@SpyBean会改变bean在context中的状态,为了保证每个test运行时context不被污染而进行刷新,属于正常现象,是springboot的默认行为。但由此会导致其他不可预料的错误。
springboot提供了spirng-boot-starter-test以供开发者使用单元测试,其中org.springframework.boot.test的mockito包,是springboot对org.mockito的增强替换,@MockBean和@SpyBean是主要的mock注解。
tests使用@MockBean和@SpyBean会导致bean在spring test context中缓存的cache key变化,springboot默认缓存context,当顺序执行的两个tests分别依赖不同的但需要被mock的bean或者同一个bean而在其中一个test中需要被mock时(或者其他会污染context的行为),spring test context发生变化,进而引起运行第二个test前刷新context。
于是多个tests重复启动spring test context(较早的context不会自动关闭?jvm中已存在class meta?),不能保证每个tests的执行上下文的独立性、隔离性,某一些bean在被多次创建后会出现异常。
参考issue
Spring boot test: context loaded for every test?
Context not being reused in tests when MockBeans are used
Context isn’t cached when MockBean using
@SpyBean makes context restart between two tests
文档释义
Mocking and Spying Beans
Context Management and Caching
解决方案
快速方案
一、对于非web工程
将用例中使用的mock变量放到父类,这样所有的用例类都使用同一个上下文,具体的mock放到实际的测试用例类上。
//测试父类
@RunWith(SpringJUnit4ClassRunner.class)
public class XxxTestBase {@MockBeanprivate BeanService1 beanService1;@MockBeanprivate BeanService2 beanService2;@MockBeanprivate BeanService2 beanService2;
}//具体的测试类
public class ConcreteTest extends XxxTestBase {@Testpublic void test() {beanService2.doTest();}}
二、对于web工程
如果是web工程,spring context刷新会导致端口冲突,通过设置端口随机来避免。
@springbootTest(class=SOFABootTestApplication.class, WebEnironment=WebEnvironment.RANDOM_PORT)
参考文档:Testing Spring Boot Applications
可能潜在的问题
1.把该bean不需要被mock的方法一起mock了(@SpyBean替换@MockBean?);
2.一些场景下该bean不需要被mock,而上下文中该bean是被mock的;
3.web工程设置为端口随机,可能会导致某些依赖端口的用例出现失败;
相关阅读
Do You Really Need @DirtiesContext?
Annotation Type DirtiesContext
其他资料
Mockito.mock() vs @Mock vs @MockBean
Think Twice Before Using @MockBean
谨慎使用 @MockBean注解相关推荐
- PowerMock简介及常见注解解释
一.什么是PowerMock PowerMock是一个Java单元测试模拟框架,用于解决测试问题,它是在其他的单元测试模拟框架的基础上做出了拓展.通过提供定制的类加载器以及一些字节码篡改技巧的应用,P ...
- SpringBoot+Spock的熟悉之路(二):Spock,Mock和Mockitio的关系
Spock,Mock和Mockitio的关系 前言 环境 依赖 Spock和Mockito Mockito的简述 Mock,Stub和Spy 数据准备 Mock Stub Spy Spock中的Moc ...
- Spring Boot 的单元测试和集成测试
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 作者 | 万想 来源 | 公众号「锅外的大佬」 学习如何使用本教程中提供的工具,并在 Spr ...
- 在Docker中运行Spring Boot的高级功能测试
来源:SpringForAll社区 想要学习更多有关Spring Boot项目的功能测试吗?阅读这篇博客可以让您掌握如何利用Docker容器进行测试. 概览 本文重点介绍如何使用Spring Boot ...
- mockito mock void方法_用过举手!SpringBoot 单元测试利器Mockito
Mockito 是一种 Java mock 框架,他主要是用来做 mock 测试的,他可以模拟任何 Spring 管理的 bean.模拟方法的返回值.模拟抛出异常...等,在了解 Mockito 的具 ...
- mockito mock void方法_一文让你快速上手 Mockito 单元测试框架
前言 在计算机编程中,单元测试是一种软件测试方法,通过该方法可以测试源代码的各个单元功能是否适合使用.为代码编写单元测试有很多好处,包括可以及早的发现代码错误,促进更改,简化集成,方便代码重构以及许多 ...
- SpringBoot系列: 单元测试2
之前发了SpringBoot 单元测试的博客, https://www.cnblogs.com/harrychinese/p/springboot_unittesting.html , 内容较少, 现 ...
- cleanmymac3.9.6_Spring Boot中文参考指南(2.1.6) 46.3.6、使用 JMX
上一篇[46.3.测试 Spring Boot 应用程序] 下一篇[46.3.11.自动配置的Spring WebFlux测试] 英文原文:https://docs.spring.io/spring- ...
- SpringBoot - 单元测试利器Mockito入门
文章目录 Mock 测试 What's Mockito 使用 Mockito pom依赖 Demo Code [常规操作] [Mockito] thenReturn thenThrow verify ...
最新文章
- 作为一个程序员为什么要写博客?
- java 注解 payload_spring – 如何使用注释配置PayloadValidatingInterceptor
- Java并发编程-并发工具包java.util.concurrent使用指南
- 存储 萤石云_同时用过小米米家智能猫眼(带屏)与萤石dp1s智能门铃之后的感受...
- 核心API最佳实践——JDK日志分级
- 互斥锁和读写锁的区别
- 程序员应该知道的一些很cool网站
- wireshark网络分析就这么简单 pdf_用了这么久才发现!原来PDF提取文字这么简单,看完涨知识了...
- Numpy.where()
- matlab的gaot在哪里,最权威遗传算法工具箱GAOT(gaot)安装方法
- python花瓣飘零_PYTHON抓取花瓣网高清美图
- Windows安装GoldenDict
- android js下载地址,js点击下载跳转iOS或安卓
- ESP8266 阿里云物联网平台 (详细步骤)
- 242. 有效的字母异位词 349. 两个数组的交集
- 区块链DApp从零开始学 (二) | 超详细 DApp创建 | 发行代币token | 宠物领养
- 网络基础—HTTP、HTPPS、GET、POST、Socket
- 仿新浪微博的插入#话题#
- volatility内存取证学习,美亚杯比赛版,密码+注册表
- 深度学习——神经网络的种类(前馈神经网络,反馈神经网络,图网络)