Basic Mockito Usage
Maven Dependency Maven
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <dependency > <groupId > org.mockito</groupId > <artifactId > mockito-core</artifactId > <version > 5.11.0</version > <scope > test</scope > </dependency > <dependency > <groupId > org.mockito</groupId > <artifactId > mockito-junit-jupiter</artifactId > <version > 5.11.0</version > <scope > test</scope > </dependency >
If it is a spring project then include spring-boot-starter-test
dependency. spring-boot-starter-test
dependency already includes mockito-core and mockito-junit-jupiter dependency.
Basic Usage Entity class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Data @NoArgsConstructor @AllArgsConstructor @Entity public class Item { @Id @GeneratedValue(strategy = GenerationType.AUTO) Long id; String name; int price; }
Repo class
1 2 3 4 5 6 @Repository public interface ItemRepo extends JpaRepository <Item, Long> { List<Item> findByName (String name) ; }
Service class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Service public class ItemService { private final ItemRepo itemRepository; @Autowired public ItemService (ItemRepo itemRepository) { this .itemRepository= itemRepository; } public Item findById (Long id) { return itemRepository.findById(id).orElse(null ); } public List<Item> findByName (String name) { return itemRepository.findByName(name); } }
Unit test for Service class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import static org.mockito.Mockito.*;import java.util.Optional;import org.junit.jupiter.api.Assertions;import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;public class ItemServiceTest { private ItemService itemService; private ItemRepo itemRepo; @BeforeEach public void init () { itemRepo = mock(ItemRepo.class); itemService = new ItemService (itemRepo); } @Test public void testFindById () { Item item = new Item (); item.setId(1L ); item.setName("MacBook" ); when(itemRepo.findById(1L )).thenReturn(Optional.of(item)); Item itemFound = itemService.findById(1L ); Assertions.assertEquals("MacBook" , itemFound.getName() ); verify(itemRepo, times(1 )).findById(1L ); } }
use static import to import mockito methods
1 import static org.mockito.Mockito.*;
Mock is created by mock()
method
Stubbing Basic stubbing
1 when(itemRepo.findById(1L )).thenReturn(Optional.of(item));
Stubbing exception example test
1 2 3 4 5 6 7 8 9 10 11 @Test public void testFindById_error () { Item item = new Item (); item.setId(1L ); item.setName("MacBook" ); when(itemRepo.findById(1L )).thenThrow(new RuntimeException ("Some Exception" )); Assertions.assertThrows(RuntimeException.class, () -> itemService.findById(1L )); }
Stubbing exception for void return type method is different. We need to use doThrow()
method because when() needs a return type.
1 2 3 List<String> mockList = mock(List.class); doThrow(new RuntimeException ("Some Exception" )).when(mockList).add("123" ); mockList.add("123" );
Matchers Mockito use equals method to match argument. If more flexibility is required, we can use matchers such as any(), anyInt(), anyLong(), anyString(), eq()…
1 2 3 4 when(itemRepo.findById(any())).thenReturn(Optional.of(item)); verify(itemRepo).findById(eq(1L ));
If you are using argument matchers, all arguments have to be provided by matchers.
see ArgumentMatchers class for all matchers
Verify Number of invocations You can verify the number of times a method is called. times(1) is the default.
1 2 3 4 5 6 7 8 9 10 verify(itemRepo).findByName("MacBook" ); verify(itemRepo, times(2 )).findByName("MacBook" ); verify(itemRepo, never()).findByName("MacBook" ); verify(itemRepo, atLeastOnce()).findByName("MacBook" );
Verify Invocation Order use InOrder to verify invocation order.
1 2 3 4 5 6 7 8 itemService.findById(1L ); itemService.findById(2L ); InOrder inOrder = inOrder(itemRepo);inOrder.verify(itemRepo).findById(1L ); inOrder.verify(itemRepo).findById(2L );
Verify no more interactions verifyNoMoreInteractions()
- Verifies that no interactions happened on given mocks.
1 verifyNoMoreInteractions(mockObject);
Argument Captor use ArgumentCaptor to capture argument values and further assertions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void testCaptor () { Item item = new Item (); item.setId(1L ); item.setName("MacBook" ); when(itemRepo.findByName("MacBook" )).thenReturn(List.of(item)); itemService.findByName("MacBook" ); ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class); verify(itemRepo).findByName(argument.capture()); Assertions.assertEquals(argument.getValue(), "MacBook" ); }
Annotation @Mock We can use @Mock annotation to create mock. This often results in more readable code.
1 2 3 4 5 6 7 8 9 10 11 12 13 public class ItemServiceTest { @Mock private ItemRepo itemRepo; private ItemService itemService; @BeforeEach public void setup () { MockitoAnnotations.openMocks(this ); itemService = new ItemService (itemRepo); } }
MockitoAnnotations.openMocks(this)
initializes fields annotated with Mockito annotations.
If using Junit5, then don’t need to execute MockitoAnnotations.openMocks(this)
, just annotate the test class with @ExtendWith(MockitoExtension.class)
1 2 3 4 5 6 7 8 9 10 11 12 13 @ExtendWith(MockitoExtension.class) public class ItemServiceTest { @Mock private ItemRepo itemRepo; private ItemService itemService; @BeforeEach public void setup () { itemService = new ItemService (itemRepo); } }
@InjectMocks @InjectMocks mark a field on which injection should be performed.
1 2 3 4 5 6 7 8 9 10 @ExtendWith(MockitoExtension.class) public class ItemServiceTest { @Mock private ItemRepo itemRepo; @InjectMocks private ItemService itemService; }
@Captor With annotation enabled, we can also use @Captor
annotation to create ArgumentCaptor.
1 2 @Captor private ArgumentCaptor<String> argument;
Reference