@Mock、@Spy、@MockBean 和 @SpyBean 注解的区别

简介

@Mock、@Spy、@MockBean 和 @SpyBean 是在 **单元测试**中用于**模拟对象行为**的注解。它们都属于 **Mockito** 或 **Spring** 测试框架的功能,主要用于隔离测试中的依赖,创建 mock 对象或部分 mock 对象(spy),从而可以对被测代码进行更精确的测试。

主要区别和对比

注解

定义

作用域

特点

用途

@Mock

使用 Mockito 创建一个 mock 对象,它是完全模拟的,不会调用真实方法。

Mockito 原生注解

不会调用真实方法,所有方法都需要配置

单元测试

@Spy

Mockito 创建一个 spy 对象,它会部分模拟对象,未被模拟的方法会执行真实逻辑。

Mockito 原生注解

真实对象的部分方法会被执行

单元测试        

@MockBean

使用 Spring Boot 进行测试时创建一个 mock 对象,替换 Spring 应用上下文中的真实 Bean

Spring Boot 测试

在 Spring 上下文中完全替换真实 Bean

集成测试

@SpyBean

使用 Spring Boot 进行测试时创建一个 spy 对象,部分模拟 Bean,其他方法执行真实逻辑

Spring Boot 测试

在 Spring 上下文中部分替换真实 Bean

集成测试

详细说明

1. @Mock(Mockito 注解)

定义:使用 @Mock 注解来创建一个 mock 对象,它是完全模拟的。这个对象的所有方法都不会调用真实的逻辑,除非你使用 Mockito.when() 来为其配置返回值。

特点:@Mock 完全模拟对象的行为。它不会调用任何真实的对象方法。你需要通过 Mockito.when() 来指定它的方法行为。

示例:

@Mock
private SomeService someServiceMock;  // 完全模拟

@Test
void testSomeMethod() {
    when(someServiceMock.someMethod()).thenReturn("Mocked value");
    String result = someServiceMock.someMethod();  // 返回 "Mocked value"
    assertEquals("Mocked value", result);
}

使用场景:当你不关心对象的内部逻辑,只需要模拟某个对象的行为来隔离单元测试时使用。

2. @Spy(Mockito 注解)

定义:使用 @Spy 注解来创建一个 spy 对象,它会部分模拟对象行为。spy 对象会调用未被显式配置的真实方法,只有那些被模拟的方法会返回预定义的值。

特点:@Spy 可以调用真实的对象方法。如果你只需要部分模拟某些方法,并让其他方法保持原始行为,可以使用 @Spy。

示例:

@Spy
private SomeService someServiceSpy;  // 部分模拟

@Test
void testSomeMethod() {
    doReturn("Mocked value").when(someServiceSpy).someMethod();
    String result = someServiceSpy.someMethod();  // 返回 "Mocked value"
    assertEquals("Mocked value", result);
    verify(someServiceSpy, times(1)).someMethod();  // 验证真实方法被调用
}

使用场景:当你希望测试对象的部分真实逻辑,但又希望在某些方法上进行模拟时,使用 @Spy。

3. @MockBean(Spring Boot 测试注解)

定义:@MockBean 是 Spring Boot 提供的注解,它用于在测试中创建一个 mock 对象,并将其注入到 Spring 上下文中,替换掉原来的真实 Bean

特点:@MockBean 会将 Spring 应用上下文中的真实 Bean 替换为一个 mock 对象。它主要用于 集成测试,用于隔离某些 Bean 的行为。

示例:

@MockBean
private SomeService someServiceMock;  // 替换 Spring 上下文中的真实 SomeService

@Test
void testSomeMethod() {
    when(someServiceMock.someMethod()).thenReturn("Mocked value");
    String result = someServiceMock.someMethod();  // 返回 "Mocked value"
    assertEquals("Mocked value", result);
}

使用场景:在使用 Spring Boot 进行集成测试时,你希望替换掉 Spring 上下文中的某些 Bean,避免它们的真实行为干扰测试,使用 @MockBean 来替换。

4. @SpyBean(Spring Boot 测试注解)

定义:@SpyBean 是 Spring Boot 提供的注解,用于在 Spring 上下文中将一个 Bean 替换为 spy 对象。它可以部分模拟某些方法,而保留其他方法的真实逻辑。

特点:@SpyBean 会将 Spring 应用上下文中的 Bean 替换为一个 spy 对象。你可以让未模拟的方法调用真实逻辑,同时在某些方法上进行模拟。

示例:

@SpyBean
private SomeService someServiceSpy;  // 替换 Spring 上下文中的 SomeService,部分模拟

@Test
void testSomeMethod() {
    doReturn("Mocked value").when(someServiceSpy).someMethod();
    String result = someServiceSpy.someMethod();  // 返回 "Mocked value"
    assertEquals("Mocked value", result);
}

使用场景:在使用 Spring Boot 进行集成测试时,@SpyBean 用于部分模拟 Spring 上下文中的某个 Bean,但你希望部分保留真实逻辑。

总结对比:

功能

@Mock

@Spy

@MockBean

@SpyBean

来源

Mockito

Mockito

Spring Boot

Spring Boot

作用域

局部测试对象

局部测试对象

Spring 上下文

Spring 上下文

调用真实方法

不会调用真实方法

会调用未 mock 的真实方法

不会调用真实方法

会调用未 mock 的真实方法

使用场景

单元测试,用于完全模拟对象

单元测试,部分模拟对象

集成测试,替换 Spring 上下文中的 Bean

集成测试,替换 Spring 上下文中的 Bean

• @Mock 和 @Spy:用于单元测试,创建局部对象的 mock 或 spy。@Mock 完全模拟对象,@Spy 部分模拟。

• @MockBean 和 @SpyBean:用于 Spring Boot 集成测试,分别替换 Spring 上下文中的 Bean 为 mock 或 spy 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值