Mockito.mock() vs @Mock vs @MockBean

本文介绍了Mockito库中创建模拟对象的三种方式:mock()方法、@Mock注解和@MockBean注解。mock()方法允许我们在测试中指定方法行为并验证调用。@Mock注解简化了mock对象的创建,但需配合MockitoJUnitRunner或手动初始化。而@MockBean则用于Spring集成测试,它可以将模拟对象注入到Spring上下文中,替代或新增bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mockito.mock

mock()方法可以创建类或接口的模拟对象。

我们可以使用mock来指定方法的行为,并验证它们是否被调用。

举个例子:

@Test
public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() {
    //mock对象
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
    //指定mock对象的行为
    Mockito.when(localMockRepository.count()).thenReturn(0L);
 
    //调用mock对象
    long userCount = localMockRepository.count();
 
    Assert.assertEquals(0L, userCount);
    //验证localMockRepository的方法被调用
    Mockito.verify(localMockRepository).count();
}
复制代码

在使用此方法之前,不需要执行任何其他操作。我们可以使用它在类中Mock字段或者在函数中Mock局部变量。

@Mock注解

Mock注解实际上是mockito.mock()方法的缩写,同样,我们应该只在测试类中使用它。

与mock()方法不同,我们需要启用mockito注解来使用此注解。我们可以通过使用mockitojunitrunner运行测试或显式调用mockitoannotations.initmocks()方法来实现这一点。

MockitoJUnitRunner
@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();
    }
}
复制代码

相比较mock方法,Mock注解除了使代码更易读之外,还可以在出现故障时更容易找到问题,因为在错误消息中会出现字段名称。

Wanted but not invoked:
mockRepository.count();
......
Actually, there were zero interactions with this mock.
复制代码

MockBean注解

我们可以使用@mockBean注解将Mock对象添加到Spring上下文中。

Mock将替换Spring上下文中任何相同类型的现有bean,如果没有定义相同类型的bean,将添加一个新的bean。

MockBean注解在集成测试中很有用,在集成测试中需要模拟特定bean,例如外部Service。

如果需要使用Mockbean注解,需要使用SpringRunner(Junit5 中是SpringExtention)

@RunWith(SpringRunner.class)
public class MockBeanAnnotationIntegrationTest {
     
    //mock对象
    @MockBean
    UserRepository mockRepository;
     
    @Autowired
    ApplicationContext context;
     
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        //指定mock对象的行为
        Mockito.when(mockRepository.count()).thenReturn(123L);
 
        //通过应用程序上下文获取Mock的对象
        //也可以直接调用mockRepository.count()方法
        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();
 
        Assert.assertEquals(123L, userCount);
        //验证被调用的就是Mock的对象
        Mockito.verify(mockRepository).count();
    }
}
复制代码

可以看到,通过上下文获取的对象,正是通过mockBean注解mock的对象。

### 使用 Mockito 的 `mockStatic` 方法实现 `doNothing` 功能 在 Mockito 中,静态方法的模拟通常通过 `mockStatic` 来完成。为了使静态方法的行为类似于 `doNothing()`,可以结合 `Mockito.mockStatic` 和 `when(...).thenReturn(...)` 或其他行为定义来实现。 以下是具体的代码示例: ```java import static org.mockito.Mockito.*; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; public class StaticMethodTest { @Test public void testMockStaticWithDoNothing() { try (MockedStatic<UtilityClass> mockedStatic = mockStatic(UtilityClass.class)) { // 定义静态方法的行为为 doNothing() mockedStatic.when(() -> UtilityClass.staticMethod(anyString())).thenReturn(null); // 调用被测试的方法 new TestedClass().invokeStaticMethod(); // 验证静态方法是否被调用 mockedStatic.verify(() -> UtilityClass.staticMethod("test"), times(1)); } } private static class TestedClass { public void invokeStaticMethod() { String result = UtilityClass.staticMethod("test"); if (result == null) { System.out.println("Static method returned null as expected."); } else { throw new RuntimeException("Unexpected behavior from static method!"); } } } private static class UtilityClass { public static String staticMethod(String input) { return "Original Result"; } } } ``` #### 解析 上述代码展示了如何使用 `mockStatic` 实现类似 `doNothing()` 的功能: - 创建了一个 `MockedStatic` 对象用于管理对目标类中静态方法的模拟[^4]。 - 使用 `when(...).thenReturn(null)` 将静态方法的结果设置为空值,从而达到不执行任何操作的效果[^5]。 - 在实际应用中,可以通过验证静态方法的调用来确认其行为是否符合预期[^3]。 需要注意的是,`mockStatic` 是从 Mockito 3.4.0 开始引入的功能,因此需要确保使用的版本支持该特性。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值