赞
踩
Mockito是一个流行的Java mocking框架,它允许开发者以简单直观的方式创建和使用模拟对象(mocks)。Mockito特别适用于在Spring Boot环境中进行单元测试,因为它能够轻松模拟Spring应用中的服务、存储库、客户端和其他组件。通过使用Mockito,开发者可以模拟外部依赖,从而使单元测试更加独立和可靠。这不仅有助于减少测试时对真实系统状态的依赖,而且还允许开发者模拟各种场景,包括异常情况和边缘情况。
假设你有一个服务 BookService
,它依赖于一个DAO(数据访问对象) BookRepository
。你可以使用Mockito来模拟 BookRepository
的行为。
- @SpringBootTest
- public class BookServiceTest {
-
- @Mock
- private BookRepository bookRepository;
-
- @InjectMocks
- private BookService bookService;
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.openMocks(this);
- }
-
- @Test
- public void testFindBookById() {
- Book mockBook = new Book(1L, "Mockito in Action", "John Doe");
- when(bookRepository.findById(1L)).thenReturn(Optional.of(mockBook));
-
- Book result = bookService.findBookById(1L);
-
- assertEquals("Mockito in Action", result.getTitle());
- }
- }
如果你想测试一个控制器,你可以使用Mockito来模拟服务层的方法,并使用 MockMvc
来模拟HTTP请求。
- @WebMvcTest(BookController.class)
- 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(bookService.findBookById(1L)).thenReturn(mockBook);
-
- mockMvc.perform(get("/books/1"))
- .andExpect(status().isOk())
- .andExpect(jsonPath("$.title").value("Mockito for Beginners"));
- }
- }
你还可以使用Mockito来测试异常情况。
- @SpringBootTest
- public class BookServiceTest {
-
- @Mock
- private BookRepository bookRepository;
-
- @InjectMocks
- private BookService bookService;
-
- @Test
- public void testBookNotFound() {
- when(bookRepository.findById(1L)).thenReturn(Optional.empty());
-
- assertThrows(BookNotFoundException.class, () -> {
- bookService.findBookById(1L);
- });
- }
- }
如果你的服务层使用了REST客户端来调用外部API,你可以使用Mockito来模拟这些调用。
- @SpringBootTest
- public class ExternalServiceTest {
-
- @Mock
- private RestTemplate restTemplate;
-
- @InjectMocks
- private ExternalService externalService;
-
- @Test
- public void testGetExternalData() {
- String response = "{\"key\":\"value\"}";
- when(restTemplate.getForObject("http://external-api.com/data", String.class))
- .thenReturn(response);
-
- String result = externalService.getExternalData();
-
- assertEquals("{\"key\":\"value\"}", result);
- }
- }
在某些情况下,你可能想要验证服务层调用了DAO的正确方法并且传递了正确的参数。Mockito的参数捕获功能可以用于这种场景。
- @SpringBootTest
- public class UserServiceTest {
-
- @Mock
- private UserRepository userRepository;
-
- @InjectMocks
- private UserService userService;
-
- @Test
- public void testCreateUser() {
- User user = new User("JohnDoe", "john@doe.com");
-
- userService.createUser(user);
-
- ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
- verify(userRepository).save(userArgumentCaptor.capture());
- User capturedUser = userArgumentCaptor.getValue();
-
- assertEquals("JohnDoe", capturedUser.getUsername());
- }
- }
从Mockito 3.4.0开始,你可以模拟静态方法。这在测试使用了静态工具方法的代码时特别有用。
- @SpringBootTest
- public class UtilityServiceTest {
-
- @Test
- public void testStaticMethod() {
- try (MockedStatic<UtilityClass> mockedStatic = Mockito.mockStatic(UtilityClass.class)) {
- mockedStatic.when(() -> UtilityClass.staticMethod("input")).thenReturn("mocked output");
-
- String result = UtilityService.callStaticMethod("input");
-
- assertEquals("mocked output", result);
- }
- }
- }
有时你需要模拟一个方法在连续调用时返回不同的值或抛出异常。
- @SpringBootTest
- public class ProductServiceTest {
-
- @Mock
- private ProductRepository productRepository;
-
- @InjectMocks
- private ProductService productService;
-
- @Test
- public void testProductAvailability() {
- when(productRepository.checkAvailability(anyInt()))
- .thenReturn(true)
- .thenReturn(false);
-
- assertTrue(productService.isProductAvailable(123));
- assertFalse(productService.isProductAvailable(123));
- }
- }
在某些情况下,你可能不关心传递给mock方法的确切参数值。在这种情况下,可以使用Mockito的ArgumentMatchers
。
- @SpringBootTest
- public class NotificationServiceTest {
-
- @Mock
- private EmailClient emailClient;
-
- @InjectMocks
- private NotificationService notificationService;
-
- @Test
- public void testSendEmail() {
- notificationService.sendEmail("hello@example.com", "Hello");
-
- verify(emailClient).sendEmail(anyString(), eq("Hello"));
- }
- }
如果需要模拟一个返回void的方法,可以使用doNothing()
、doThrow()
等。
- @SpringBootTest
- public class AuditServiceTest {
-
- @Mock
- private AuditLogger auditLogger;
-
- @InjectMocks
- private UserService userService;
-
- @Test
- public void testUserCreationWithAudit() {
- doNothing().when(auditLogger).log(anyString());
-
- userService.createUser(new User("JaneDoe", "jane@doe.com"));
-
- verify(auditLogger).log(contains("User created:"));
- }
- }
-
当需要模拟泛型方法时,可以使用any()
方法来表示任意类型的参数。
- @SpringBootTest
- public class CacheServiceTest {
-
- @Mock
- private CacheManager cacheManager;
-
- @InjectMocks
- private ProductService productService;
-
- @Test
- public void testCaching() {
- Product mockProduct = new Product("P123", "Mock Product");
-
- when(cacheManager.getFromCache(any(), any())).thenReturn(mockProduct);
-
- Product result = productService.getProduct("P123");
-
- assertEquals("Mock Product", result.getName());
- }
- }
有时你可能需要部分模拟一个对象。在这种情况下,可以使用@Spy
注解。
- @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 = orderService.processOrder(order);
-
- assertTrue(result);
- }
- }
如果你需要验证mock对象上的方法调用顺序,可以使用InOrder
。
- @SpringBootTest
- public class TransactionServiceTest {
-
- @Mock
- private Database database;
-
- @InjectMocks
- private TransactionService transactionService;
-
- @Test
- public void testTransactionOrder() {
- transactionService.performTransaction();
-
- InOrder inOrder = inOrder(database);
- inOrder.verify(database).beginTransaction();
- inOrder.verify(database).commitTransaction();
- }
- }
通过使用Mockito,可以模拟服务层、存储库、REST客户端等组件,而无需依赖实际的实现。这样不仅可以减少测试对外部系统的依赖,还可以模拟异常情况和边缘用例,从而确保代码在各种环境下的稳健性。此外,Mockito的灵活性使得它可以轻松集成到现有的Spring Boot项目中,无论是对于简单的单元测试还是更复杂的集成测试。总而言之,Mockito是Spring Boot开发者的强大工具,它可以提高测试的有效性和效率,从而帮助构建更健壮、可靠的Spring应用。
行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 786229024,里面有各种测试开发资料和技术可以一起交流哦。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。