Mockito.mock() vs @Mock vs @MockBean

Mockito.mock

mock()方法能夠建立類或接口的模擬對象。bash

咱們能夠使用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局部變量。ui

@Mock註解

Mock註解其實是mockito.mock()方法的縮寫,一樣,咱們應該只在測試類中使用它。this

與mock()方法不一樣,咱們須要啓用mockito註解來使用此註解。咱們能夠經過使用mockitojunitrunner運行測試或顯式調用mockitoannotations.initmocks()方法來實現這一點。spa

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註解除了使代碼更易讀以外,還能夠在出現故障時更容易找到問題,由於在錯誤消息中會出現字段名稱。code

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

若是須要使用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的對象。

相關文章
相關標籤/搜索