1. 概述
在本教程中,我們將討論如何使用依賴注入將Mockito mock對象插入到Spring Bean中進行單元測試。
在現實世界的應用程序中,當組件依賴於訪問外部系統時,提供適當的測試隔離至關重要,以便我們可以在不涉及整個類層次結構的情況下,專注於測試給定單元的功能。
注入mock是一種乾淨的方法,可以引入這種隔離。
2. Maven 依賴
我們需要以下 Maven 依賴項用於單元測試和 Mock 對象:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.12.0</version>
</dependency>我們決定使用 Spring Boot 作為本示例,但經典的 Spring 也可以正常工作。
3. 編寫測試
3.1. 業務邏輯
首先,讓我們創建一個簡單的服務,我們將對其進行測試:
@Service
public class NameService {
public String getUserName(String id) {
return "Real user name";
}
}然後我們將它注入到 UserService 類中:
@Service
public class UserService {
private NameService nameService;
@Autowired
public UserService(NameService nameService) {
this.nameService = nameService;
}
public String getUserName(String id) {
return nameService.getUserName(id);
}
}對於本文檔,提供的類無論提供何 ID 都返回單個名稱。 這樣做是為了避免我們被複雜的邏輯測試所分心。
我們還需要一個標準的 Spring Boot 主類來掃描 Bean 並初始化應用程序:
@SpringBootApplication
public class MocksApplication {
public static void main(String[] args) {
SpringApplication.run(MocksApplication.class, args);
}
}3.2. 測試
現在我們來探討測試邏輯。首先,我們需要配置測試應用程序上下文:
@Profile("test")
@Configuration
public class NameServiceTestConfiguration {
@Bean
@Primary
public NameService nameService() {
return Mockito.mock(NameService.class);
}
}@Profile 註解告訴 Spring 在“test” 激活時僅應用此配置。@Primary 註解確保該實例在自動裝入時被使用,而不是真實的實例。方法本身創建並返回一個 Mockito 對 NameService 類的模擬對象。
現在我們可以編寫單元測試:
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MocksApplication.class)
public class UserServiceUnitTest {
@Autowired
private UserService userService;
@Autowired
private NameService nameService;
@Test
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
Mockito.when(nameService.getUserName("SomeId")).thenReturn("Mock user name");
String testName = userService.getUserName("SomeId");
Assert.assertEquals("Mock user name", testName);
}
}我們使用 @ActiveProfiles 註解來啓用“test”環境並激活我們之前編寫的mock配置。 結果,Spring 自動注入了一個真實的 UserService 類實例,但注入了一個 NameService 類的mock。 整個測試用例是一個典型的 JUnit + Mockito 測試。 我們配置mock的行為,然後調用我們想要測試的方法,並斷言它返回我們期望的值。
此外,雖然不推薦,但也可以避免在測試中使用環境配置文件。 要做到這一點,我們移除 @Profile 和 @ActiveProfiles 註解,並向 UserServiceTest 類添加 @ContextConfiguration(classes = NameServiceTestConfiguration.class) 註解。
4. 結論
在本文中,我們學習瞭如何輕鬆地將 Mockito 模擬對象注入到 Spring Bean 中。