Mockito.mock () contro @Mock contro @MockBean

1. Panoramica

In questo rapido tutorial, esamineremo tre diversi modi per creare oggetti fittizi e come differiscono tra loro: con Mockito e con il supporto per il mocking di Spring.

2. Mockito.mock ()

Il metodo Mockito.mock () ci consente di creare un oggetto fittizio di una classe o di un'interfaccia.

Quindi, possiamo usare il mock per stub restituire i valori per i suoi metodi e verificare se sono stati chiamati.

Diamo un'occhiata a un esempio:

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

Questo metodo non necessita di nient'altro da fare prima di poter essere utilizzato. Possiamo usarlo per creare campi di classi fittizie e simulazioni locali in un metodo.

3. Annotazione @Mock di Mockito

Questa annotazione è una scorciatoia per il metodo Mockito.mock () . Inoltre, dovremmo usarlo solo in una classe di test. A differenza del metodo mock () , dobbiamo abilitare le annotazioni Mockito per utilizzare questa annotazione.

Possiamo farlo utilizzando il MockitoJUnitRunner per eseguire il test o chiamando esplicitamente il metodo MockitoAnnotations.initMocks () .

Diamo un'occhiata a un esempio utilizzando 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(); } }

Oltre a rendere il codice più leggibile, @Mock rende più facile trovare il problema simulato in caso di errore, poiché il nome del campo appare nel messaggio di errore:

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) 

Inoltre, se utilizzato insieme a @InjectMocks , può ridurre in modo significativo la quantità di codice di installazione.

4. Annotazione @MockBean di Spring Boot

Possiamo usare @MockBean per aggiungere oggetti fittizi al contesto dell'applicazione Spring. Il mock sostituirà qualsiasi bean esistente dello stesso tipo nel contesto dell'applicazione.

Se non viene definito alcun bean dello stesso tipo, ne verrà aggiunto uno nuovo. Questa annotazione è utile nei test di integrazione in cui un particolare bean, ad esempio un servizio esterno, deve essere deriso.

Per utilizzare questa annotazione, dobbiamo utilizzare SpringRunner per eseguire il test:

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

Quando usiamo l'annotazione su un campo, oltre ad essere registrati nel contesto dell'applicazione, anche il mock verrà iniettato nel campo.

Ciò è evidente nel codice sopra. Qui, abbiamo utilizzato il mock UserRepository iniettato per bloccare il metodo di conteggio . Abbiamo quindi utilizzato il bean dal contesto dell'applicazione per verificare che sia effettivamente il mocked bean.

5. conclusione

In questo articolo, abbiamo visto come differiscono i tre metodi per la creazione di oggetti fittizi e come ciascuno può essere utilizzato.

Il codice sorgente che accompagna questo articolo è disponibile su GitHub.