知識庫 / Spring RSS 訂閱

Mockito 中的 mock()、@Mock 和 @MockBean 區別

Spring,Testing
HongKong
6
01:44 PM · Dec 06 ,2025

1. 概述

在本快速教程中,我們將探討三種使用 Mockito 和 Spring mocking 支持創建模擬對象的不同方法。我們還將討論它們之間的差異。

2. Mockito.mock()

Mockito.mock() 方法允許我們創建類或接口的 Mock 對象。

我們可以使用 Mock 對象來為它的方法設置返回值,並驗證這些方法是否被調用。

以下是一個示例:

@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。

3. Mockito 的 <em @Mock@ 註解

此註解是 <em Mockito.mock() 方法的簡寫。需要注意的是,我們應該僅在測試類中使用它。與 <em mock() 方法不同,使用此註解需要啓用 Mockito 註解。

我們可以通過以下方式進行操作:使用 <em MockitoJUnitRunner 運行測試,或者顯式調用 <em MockitoAnnotations.initMocks() 方法。

讓我們以使用 <em 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();
    }
}

除了使代碼更易於閲讀之外,<em@Mock還便於在出現故障時查找mock對象,因為字段名會在故障信息中出現:

Wanted but not invoked:
mockRepository.count();
-> at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)
Actually, there were zero interactions with this mock.

  at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)

此外,當與@InjectMocks一起使用時,它還可以顯著減少設置代碼量。

4. Spring Boot 中的 <em @MockBean</em> 註解

我們可以使用 <em @MockBean</em>> 來向 Spring 應用上下文添加 Mock 對象。 Mock 對象將替換上下文中的同類型現有 Bean。

如果未定義同類型的 Bean,則會添加一個新的 Bean。 此註解在集成測試中非常有用,其中特定的 Bean(例如外部服務)需要被 Mock。

要使用此註解,我們需要使用 <em SpringRunner</em>> 運行測試:

@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();
    }
}

當我們對字段使用註解時,mock 會被注入到該字段中,同時也會在應用程序上下文中進行註冊。

這一點在上面的代碼中可以明顯看出。我們使用了注入的 UserRepository  mock 來模擬 count  方法 然後我們使用來自應用程序上下文的 Bean 來驗證它確實是模擬的 Bean。

5. 結論

在本文中,我們探討了創建模擬對象的三種方法的差異,以及如何利用每種方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.