前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >@Spy、@SpyBean、@MockBean、@Mock、@RunWith、@ExtendWith对比

@Spy、@SpyBean、@MockBean、@Mock、@RunWith、@ExtendWith对比

原创
作者头像
查拉图斯特拉说
发布于 2023-11-09 09:57:02
发布于 2023-11-09 09:57:02
1.3K00
代码可运行
举报
文章被收录于专栏:后端架构后端架构
运行总次数:0
代码可运行

前言

在写单元测试中经常会用到Mockito,但是这些类似的注解非常混乱,今天总结一下相关的注解,说明其中的含义和实现例子。

Mockito.mock() vs @Mock vs @MockBean

Mockito.mock ()方法允许我们创建类或接口的模拟对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() {
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
    Mockito.when(localMockRepository.count()).thenReturn(111L);

    long userCount = localMockRepository.count();

    Assert.assertEquals(111L, userCount);
    Mockito.verify(localMockRepository).count();
}

@Mock该注释是Mockito.mock()方法的简写。需要注意的是,我们应该只在测试类中使用它。与mock()方法不同的是,我们需要启用Mockito注解才能使用该注解。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(MockitoJUnitRunner.class)
public class MockAnnotationUnitTest {
    
    @Mock
    UserRepository mockRepository;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        long userCount = mockRepository.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

@MockBean将模拟对象添加到 Spring 应用程序上下文中。模拟将替换应用程序上下文中相同类型的任何现有 bean。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(SpringRunner.class)
public class MockBeanAnnotationIntegrationTest {
    
    @MockBean
    UserRepository mockRepository;
    
    @Autowired
    ApplicationContext context;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

JUnit5 @RunWith annotation with the new @ExtendWith

在 JUnit 5 中,@RunWith注释已被更强大的@ExtendWith注释取代。

@RunWith

@RunWith注释在任何较旧的 JUnit 环境中运行 JUnit 5 测试。

JUnitPlatform类是一个基于 JUnit 4 的运行器,允许我们在 JUnit 平台上运行 JUnit 4 测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(JUnitPlatform.class)
public class GreetingsUnitTest {
    // ...
}

基于 JUnit 4 的运行器的测试迁移到 JUnit 5。我们将使用 Spring 测试作为示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { SpringTestConfiguration.class })
public class GreetingsSpringUnitTest {
    // ...
}

@ExtendWith

测试迁移到 JUnit 5,我们需要用新的@ExtendWith替换@RunWith注释:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { SpringTestConfiguration.class })
public class GreetingsSpringUnitTest {
    // ...
}

@Spy 和 @SpyBean 之间的区别

@Spy注释是 Mockito 测试框架的一部分,它创建真实对象的间谍(部分模拟),通常用于单元测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Spy
OrderRepository orderRepository;
@Spy
NotificationService notificationService;
@InjectMocks
OrderService orderService;

@Test
void givenNotificationServiceIsUsingSpy_whenOrderServiceIsCalled_thenNotificationServiceSpyShouldBeInvoked() {
    UUID orderId = UUID.randomUUID();
    Order orderInput = new Order(orderId, "Test", 1.0, "17 St Andrews Croft, Leeds ,LS17 7TP");
    doReturn(orderInput).when(orderRepository)
        .save(any());
    doReturn(true).when(notificationService)
        .raiseAlert(any(Order.class));
    Order order = orderService.save(orderInput);
    Assertions.assertNotNull(order);
    Assertions.assertEquals(orderId, order.getId());
    verify(notificationService).notify(any(Order.class));
}

Spring Boot 的@SpyBean注解

@SpyBean注解是Spring Boot特有的,用于与Spring的依赖注入进行集成测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Autowired
OrderRepository orderRepository;
@SpyBean
NotificationService notificationService;
@SpyBean
OrderService orderService;

@Test
void givenNotificationServiceIsUsingSpyBean_whenOrderServiceIsCalled_thenNotificationServiceSpyBeanShouldBeInvoked() {

    Order orderInput = new Order(null, "Test", 1.0, "17 St Andrews Croft, Leeds ,LS17 7TP");
    doReturn(true).when(notificationService)
        .raiseAlert(any(Order.class));
    Order order = orderService.save(orderInput);
    Assertions.assertNotNull(order);
    Assertions.assertNotNull(order.getId());
    verify(notificationService).notify(any(Order.class));
}

@Spy@SpyBean之间的区别

在单元测试中,我们使用@Spy,而在集成测试中,我们使用@SpyBean

如果@Spy注解的组件包含其他依赖项,我们可以在初始化时声明它们。如果在初始化期间未提供它们,系统将使用零参数构造函数(如果可用)。在@SpyBean测试的情况下,我们必须使用@Autowired注释来注入依赖组件。否则,在运行时,Spring Boot 会创建一个新实例。

如果我们在单元测试示例中使用 @SpyBean ,则 当 调用NotificationService时,测试将失败并出现NullPointerException因为OrderService需要模拟/间谍 NotificationService

同样,如果在集成测试的示例中使用@Spy ,则测试将失败并显示错误消息“Wanted but not invoked: notificationService.notify(<any com.baeldung.spytest.Order> )”,因为 Spring 应用程序context 不知道 @Spy注解的类相反,它创建一个新的NotificationService实例并将其注入到OrderService 中。

@SpyBean需要手动注入bean,但是@Spy 不需要,除非你调用了依赖

总结

@Spy、@SpyBean、@MockBean、@Mock、@RunWith、@ExtendWith,带bean的就跟集成测试有关,例如集成Spring,如果只是简单的单元测试可以配置不带Bean的,这里面最好区分的还是@RunWith和@ExtendWith,一个是JUnit4一个是JUnit5。

引用

https://www.baeldung.com/java-spring-mockito-mock-mockbean

https://www.baeldung.com/junit-5-runwith

https://www.baeldung.com/spring-spy-vs-spybean

点赞关注评论一键三连,欢迎关注公众号【i查拉图斯特拉如是说】每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RNA-seq入门实战(十一):WGCNA加权基因共表达网络分析——关联基因模块与表型
连续两次求贤令:曾经我给你带来了十万用户,但现在祝你倒闭,以及 生信技能树知识整理实习生招募,让我走大运结识了几位优秀小伙伴!大家开始根据我的ngs组学视频进行一系列公共数据集分析实战,其中几个小伙伴让我非常惊喜,不需要怎么沟通和指导,就默默的完成了一个实战!
生信技能树
2022/07/26
15.3K3
RNA-seq入门实战(十一):WGCNA加权基因共表达网络分析——关联基因模块与表型
WGCNA
加权基因共表达网络分析 (WGCNA, Weighted correlation network analysis)是用来描述不同样品之间基因关联模式的系统生物学方法,可以用来鉴定高度协同变化的基因集, 测试数据下载地址:https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/FemaleLiver-Data.zip
生信编程日常
2020/04/01
1.6K0
WGCNA
WGCNA加权基因共表达网络一步法分析学习
WGCNA是一种用于分析基因表达数据的系统生物学方法。主要用于识别在基因表达数据中呈现共表达模式的基因模块,并将这些模块与样本特征(如临床特征、表型数据)相关联,进而识别关键驱动基因或生物标志物。
凑齐六个字吧
2024/08/31
2790
WGCNA加权基因共表达网络一步法分析学习
GEO_加权共表达网络WGCNA
WGCNA(Weighted Gene Co-Expression Network Analysis,即加权基因共表达网络分析)是一种用于分析基因表达数据的系统生物学方法。WGCNA的主要目的是识别基因表达数据中的共表达模块,并研究这些模块与外部样本特征(例如,疾病状态、临床特征等)之间的关系。
sheldor没耳朵
2024/07/25
4720
GEO_加权共表达网络WGCNA
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第五步-高级可视化)
1写在前面 前面我们用WGCNA分析完成了一系列的分析,聚类分割模块。🥰 随后进一步筛选,找到与我们感兴趣的表型或者临床特征相关的模块,而且进行了模块内部分析。😘 再然后是对感兴趣模块进行功能注释,了解模块的功能及涉及的潜在机制。🥳 本期主要是介绍一些可视化的方法,大家了解一下吧。🥰 2用到的包 rm(list = ls()) library(WGCNA) library(dplyr) 3示例数据 load("FemaleLiver-01-dataInput.RData") load("FemaleLiv
生信漫卷
2023/02/24
6390
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第五步-高级可视化)
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第三步-模块与特征分析)
1写在前面 之前我们完成了WGCNA输入数据的清洗,网络构建和模块识别。😘 而且还介绍了如何对大型数据分级处理,有效地减少了内存的负担。😷 ---- 接着就是最重要的环节了,将不同module与表型或者临床特征相联系,进一步鉴定出有意义的module,并进行module内部的分析,筛选重要基因。🤒 不得不说,东西还是挺多的,而且非常重要,我们一起来试一下吧。🥰 2用到的包 rm(list = ls()) library(WGCNA) library(tidyverse) 3示例数据 load("Femal
生信漫卷
2023/02/24
5570
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第三步-模块与特征分析)
R语言实现加权共表达网络分析
WGCNA(Weighted GeneCo-Expression Network Analysis,加权共表达网络分析)分析方法旨在寻找协同表达的基因模块(module),并探索基因网络与关注的表型之间的关联关系,以及网络中的核心基因。我们今天介绍下在R语言如何实现WGCNA,此包还有一个限制那就是样本总数必须大于15。
一粒沙
2019/08/08
7.1K2
R语言实现加权共表达网络分析
WGCNA加权基因共表达网络多步法分析学习
之前笔者介绍过一步法的分析的流程: WGCNA加权基因共表达网络一步法分析学习 https://mp.weixin.qq.com/s/2Q37RcJ1pBy_WO1Es8upIg
凑齐六个字吧
2024/10/10
1850
WGCNA加权基因共表达网络多步法分析学习
WGCNA仅仅是划分基因模块,其它都是附加分析
曾老师给我分享了一篇数据挖掘的文章,里面的WGCNA非常奇怪,我之前没见过这样的模块与表型的相关性热图
生信技能树
2023/09/04
1.4K0
WGCNA仅仅是划分基因模块,其它都是附加分析
WGCNA实战练习
本文采用WGCNA官网的Tutirial 1的数据,对加权基因共表达网络分析和后续的数据挖掘的具体操作进行梳理, 数据可以从官网下载,示意图如下
生信修炼手册
2020/05/08
1.5K0
WGCNA实战练习
一文看懂WGCNA 分析(2019更新版)
不过,我这点战绩根本就算不上什么,其实这个WGCNA包已经是十多年前发表的了,仍然是广受好评及引用量一直在增加,破万也是指日可待。
生信技能树
2019/09/30
30.9K2
一文看懂WGCNA 分析(2019更新版)
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第二步补充-大数据的网络构建与模块识别)
1写在前面 之前我们完成了WGCNA输入数据的清洗,网络构建和模块识别。😘 ---- 但这里我们的示例数据内所含有的基因其实是很少的,而在实际情况中,一个简单的测序可能就要包含上万个基因,这对大家的电脑无疑是不小的压力。🤒 在WGCNA的包内其实也提供了解决方案,基本思想是分级聚类。🧐 ---- 1️⃣ 首先,我们使用快速但相对粗糙的聚类方法,用于将基因预聚类成大小接近的模块,且不超过你所设定的基因最大值。😂 2️⃣ 然后我们分别在每个模块中执行完整的网络分析。🤠 3️⃣ 最后,合并特征基因高度相关的模块。
生信漫卷
2023/02/24
4850
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第二步补充-大数据的网络构建与模块识别)
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第四步-模块的功能注释)
1写在前面 前面我们用WGCNA分析得到多个模块,其中有一些模块和我们感兴趣的表型或者临床特征是相关的。🥳 接着就是要做模块的富集分析了,帮助我们了解这些模块的基因都有哪些已知的功能,涉及到哪些通路,在哪些疾病中最为重要。🥰 现在这种做富集分析的包还是蛮多的,WGCNA包内也是内置了相关功能,不过首推的还是Y叔的clusterProfiler,在我心中真是YYDS。🫶 2用到的包 rm(list = ls()) library(WGCNA) library(tidyverse) library(cluste
生信漫卷
2023/02/24
5140
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第四步-模块的功能注释)
R中优雅的可视化WGCNA模块热图
R语言数据分析指南
2023/10/24
1.4K0
R中优雅的可视化WGCNA模块热图
WGCNA实战:识别免疫相关lncRNA
前面的推文给大家介绍了3种识别免疫相关lncRNA的方法:免疫相关lncRNA的识别
医学和生信笔记
2023/08/30
7260
WGCNA实战:识别免疫相关lncRNA
WGCNA + ssGSEA的组合分析
生物信息数据分析教程视频——16-单样本基因集富集分析(ssGSEA)用于肿瘤相关免疫细胞浸润水平评估
DoubleHelix
2023/09/06
7490
WGCNA + ssGSEA的组合分析
跟着Nature Plants学数据分析:R语言WGCNA分析完整示例
https://www.nature.com/articles/s41477-021-00897-y#data-availability
用户7010445
2023/01/06
1K0
跟着Nature Plants学数据分析:R语言WGCNA分析完整示例
加权基因共表达网络分析(WGCNA)实例
这里运行R语言包GDCRNATools的帮助文档中的例子获得胆管癌的rna表达矩阵
用户7010445
2020/03/23
2.6K0
加权基因共表达网络分析(WGCNA)实例
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第二步-网络构建与模块识别)
1写在前面 上期我们完成了WGCNA输入数据的清洗,然后进行了样本的聚类与异常值的剔除,总体来说是非常简单的。😘 这期我们继续完成WGCNA分析的第二步,网络构建和模块识别。🤒 2用到的包 rm(list = ls()) library(WGCNA) library(tidyverse) 3示例数据 load("FemaleLiver-01-dataInput.RData") 4软阈值 4.1 topology analysis 首先我们要进行soft thresholding power β的计算。🤒
生信漫卷
2023/02/24
6210
🤩 WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第二步-网络构建与模块识别)
RNAseq|WGCNA-组学数据黏合剂,代码实战-一(尽)文(力)解决文献中常见的可视化图
WGCNA (weighted gene co-expression network analysis)权重基因共表达网络分析(流程模块见下图),可将表达模式相似的基因进行聚类,并分析模块与特定性状或表型之间的关联,常用于筛选关键表型的hub基因 ,是RNAseq分析中的一块很重要的拼图。而之所以叫组学数据黏合剂是因为表型可以是患者的临床信息(生存信息,分期信息,基线信息等),可以是重测序信息肿瘤(驱动基因的变异与否,signature ,CNV信息等),可以是转录组结果(免疫浸润,risk score ,GSVA ,分子分型结果),可以是单细胞数据(celltype ,AUCell 打分)等等 。注:这些在公众号之前的文章中大多都有涉及,文末有部分链接。
生信补给站
2023/08/25
1.1K1
RNAseq|WGCNA-组学数据黏合剂,代码实战-一(尽)文(力)解决文献中常见的可视化图
推荐阅读
相关推荐
RNA-seq入门实战(十一):WGCNA加权基因共表达网络分析——关联基因模块与表型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验