Mockito is a popular Java mocking framework that allows developers to create and use mock objects (mocks) in a simple and intuitive way. Mockito is especially suitable for unit testing in Spring Boot environments because it can easily simulate services, repositories, clients, and other components in Spring applications. By using Mockito, developers can simulate external dependencies, making unit testing more independent and reliable. This not only helps reduce the dependence on real system state during testing, but also allows developers to simulate various scenarios, including exceptions and edge cases.
Example 1: Simulate the method in the service layer
Suppose you have a service BookService, which relies on a DAO (Data Access Object) BookRepository. You can use Mockito to simulate the behavior of BookRepository.
@SpringBootTest public class BookServiceTest { @Mock private BookRepository bookRepository; @InjectMocks private BookService bookService; @BeforeEach public void setup() { (this); } @Test public void testFindBookById() { Book mockBook = new Book(1L, "Mockito in Action", "John Doe"); when((1L)).thenReturn((mockBook)); Book result = (1L); assertEquals("Mockito in Action", ()); } }
Example 2: Simulating the web layer (controller)
If you want to test a controller, you can use Mockito to simulate the service layer method and useMockMvc
To simulate HTTP requests.
@WebMvcTest() public class BookControllerTest { @MockBean private BookService bookService; @Autowired private MockMvc mockMvc; @Test public void testGetBook() throws Exception { Book mockBook = new Book(1L, "Mockito for Beginners", "Jane Doe"); when((1L)).thenReturn(mockBook); (get("/books/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.title").value("Mockito for Beginners")); } }
Example 3: Simulate exceptions
You can also use Mockito to test exceptions.
@SpringBootTest public class BookServiceTest { @Mock private BookRepository bookRepository; @InjectMocks private BookService bookService; @Test public void testBookNotFound() { when((1L)).thenReturn(()); assertThrows(, () -> { (1L); }); } }
Example 4: Mocking the REST client using Mockito
If your service layer uses a REST client to call external APIs, you can use Mockito to simulate these calls.
@SpringBootTest public class ExternalServiceTest { @Mock private RestTemplate restTemplate; @InjectMocks private ExternalService externalService; @Test public void testGetExternalData() { String response = "{\"key\":\"value\"}"; when(("/data", )) .thenReturn(response); String result = (); assertEquals("{\"key\":\"value\"}", result); } }
Example 5: Parameter Capture and Verification
In some cases, you may want to verify that the service layer calls the correct method of DAO and passes the correct parameters. Mockito's parameter capture function can be used in this scenario.
@SpringBootTest public class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; @Test public void testCreateUser() { User user = new User("JohnDoe", "john@"); (user); ArgumentCaptor<User> userArgumentCaptor = (); verify(userRepository).save(()); User capturedUser = (); assertEquals("JohnDoe", ()); } }
Example 6: Simulating a static method
Starting with Mockito 3.4.0, you can simulate static methods. This is especially useful when testing code using static tool methods.
@SpringBootTest public class UtilityServiceTest { @Test public void testStaticMethod() { try (MockedStatic<UtilityClass> mockedStatic = ()) { (() -> ("input")).thenReturn("mocked output"); String result = ("input"); assertEquals("mocked output", result); } } }
Example 7: Simulating continuous calls
Sometimes you need to simulate a method that returns different values or throws exceptions when called continuously.
@SpringBootTest public class ProductServiceTest { @Mock private ProductRepository productRepository; @InjectMocks private ProductService productService; @Test public void testProductAvailability() { when((anyInt())) .thenReturn(true) .thenReturn(false); assertTrue((123)); assertFalse((123)); } }
Example 8: Using ArgumentMatchers
In some cases, you may not care about the exact parameter value passed to the mock method. In this case, Mockito'sArgumentMatchers
。
@SpringBootTest public class NotificationServiceTest { @Mock private EmailClient emailClient; @InjectMocks private NotificationService notificationService; @Test public void testSendEmail() { ("hello@", "Hello"); verify(emailClient).sendEmail(anyString(), eq("Hello")); } }
Example 9: Simulate the method to return void
If you need to simulate a method that returns void, you can usedoNothing()
、doThrow()
wait.
@SpringBootTest public class AuditServiceTest { @Mock private AuditLogger auditLogger; @InjectMocks private UserService userService; @Test public void testUserCreationWithAudit() { doNothing().when(auditLogger).log(anyString()); (new User("JaneDoe", "jane@")); verify(auditLogger).log(contains("User created:")); } }
Example 10: Simulating generic methods
When mocking generic methods are required, you can useany()
Method to represent any type of parameters.
@SpringBootTest public class CacheServiceTest { @Mock private CacheManager cacheManager; @InjectMocks private ProductService productService; @Test public void testCaching() { Product mockProduct = new Product("P123", "Mock Product"); when((any(), any())).thenReturn(mockProduct); Product result = ("P123"); assertEquals("Mock Product", ()); } }
Example 11: Using @Spy annotation
Sometimes you may need to partially mock an object. In this case, it is possible to use@Spy
annotation.
@SpringBootTest public class OrderServiceTest { @Spy private OrderProcessor orderProcessor; @InjectMocks private OrderService orderService; @Test public void testOrderProcessing() { Order order = new Order("O123", 100.0); doReturn(true).when(orderProcessor).validateOrder(order); boolean result = (order); assertTrue(result); } }
Example 12: Using InOrder
If you need to verify the order of method calls on the mock object, you can useInOrder
。
@SpringBootTest public class TransactionServiceTest { @Mock private Database database; @InjectMocks private TransactionService transactionService; @Test public void testTransactionOrder() { (); InOrder inOrder = inOrder(database); (database).beginTransaction(); (database).commitTransaction(); } }
Summarize
By using Mockito, components such as service layers, repositories, REST clients can be simulated without relying on actual implementations. This not only reduces the dependence of tests on external systems, but also simulates exceptions and edge use cases, ensuring the robustness of the code in various environments. In addition, Mockito's flexibility makes it easy to integrate into existing Spring Boot projects, whether for simple unit testing or more complex integration testing. All in all, Mockito is a powerful tool for Spring Boot developers, which can improve the effectiveness and efficiency of testing, helping to build more robust and reliable Spring applications.
The above is a detailed explanation of the example of using Mockito for unit testing in SpringBoot environment. For more information about SpringBoot Mockito unit testing, please follow my other related articles!