1. 概述
本快速教程將介紹 Spring Boot 中 <em @MockBeans 註解的使用。
2. 示例設置
在開始之前,讓我們創建一個簡單的票據驗證器示例,我們將會在本教程中反覆使用它:
public class TicketValidator {
private CustomerRepository customerRepository;
private TicketRepository ticketRepository;
public boolean validate(Long customerId, String code) {
customerRepository.findById(customerId)
.orElseThrow(() -> new RuntimeException("Customer not found"));
ticketRepository.findByCode(code)
.orElseThrow(() -> new RuntimeException("Ticket with given code not found"));
return true;
}
}在這裏,我們定義了 validate() 方法,用於檢查給定的數據是否存在於數據庫中。它依賴於 CustomerRepository 和 TicketRepository。
現在,讓我們來研究如何使用 Spring 的 @MockBean 和 @MockBeans 註解創建測試並模擬依賴項。
3. MockBean 註解
Spring 框架提供了 > 註解,用於測試目的進行模擬依賴項。 此註解允許我們定義特定 Bean 的模擬版本。 新創建的模擬 Bean 將被添加到 Spring 的 中。 因此,如果存在同類型的 Bean,則它將被替換為模擬版本。
此外,我們可以將此註解應用於我們希望模擬的字段或測試類級別。
使用 > 註解,我們可以通過模擬其依賴對象的行為來隔離我們想要測試的代碼特定部分。
現在,讓我們看看 > 在行動中的表現。 讓我們用模擬實現替換現有的 Bean:
class MockBeanTicketValidatorUnitTest {
@MockBean
private CustomerRepository customerRepository;
@Autowired
private TicketRepository ticketRepository;
@Autowired
private TicketValidator ticketValidator;
@Test
void givenUnknownCustomer_whenValidate_thenThrowException() {
String code = UUID.randomUUID().toString();
when(customerRepository.findById(any())).thenReturn(Optional.empty());
assertThrows(RuntimeException.class, () -> ticketValidator.validate(1L, code));
}
}在這裏,我們對 CustomerRepository 字段進行了標註,使用了 @MockBean 註解。Spring 將 Mock 對象注入到該字段中,並將其添加到應用程序上下文中。
需要注意的是,我們不能使用 @MockBean 註解來在應用程序上下文刷新期間模擬 Bean 的行為。
此外,該註解被定義為 @Repeatable,這允許我們在類級別上多次定義相同的註解:
@MockBean(CustomerRepository.class)
@MockBean(TicketRepository.class)
@SpringBootTest(classes = Application.class)
class MockBeanTicketValidatorUnitTest {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private TicketRepository ticketRepository;
@Autowired
private TicketValidator ticketValidator;
// ...
}4. <em @MockBeans</em>> 註解
現在我們已經討論了 <em @MockBean</em>> 註解,接下來我們繼續討論 <em @MockBeans</em>> 註解。簡單來説,這個註解代表多個 <em @MockBean</em>> 註解的聚合,並作為它們的容器。
此外,它也有助於組織測試用例。我們可以將多個 Mock 對象放在同一個地方定義,使測試類更乾淨、更易於組織。 此外,它在在多個測試類中重用 Mock Bean 時也很有用。
我們可以將 <em @MockBeans</em>> 作為我們之前看到的可重複的 <em @MockBean</em>> 解決方案的替代方案:
@MockBeans({@MockBean(CustomerRepository.class), @MockBean(TicketRepository.class)})
@SpringBootTest(classes = Application.class)
class MockBeansTicketValidatorUnitTest {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private TicketRepository ticketRepository;
@Autowired
private TicketValidator ticketValidator;
// ...
}需要注意的是,我們使用了@Autowired註解來標記我們想要進行模擬的 Bean。
此外,這種方法與在每個字段上定義@MockBean註解在功能上的差異無關。但是,如果我們在使用 Java 8 或更高版本時,@MockBeans註解可能顯得多餘,因為 Java 支持可重複的註解。
@MockBeans註解的主要思想是允許開發者在一個地方指定 Mock Bean。
5. 結論
在本文中,我們學習瞭如何在定義測試中的 Mock 對象時使用 <em @MockBeans</em> 註解。
總結一下,我們可以使用 <em @MockBeans</em> 註解來將多個 <em @MockBean</em> 註解組合在一起,並在一個地方定義所有 Mock 對象。