1. 概述
當進行涉及使用 Jackson 序列化 JSON 的代碼單元測試時,模擬(mock)ObjectMapper#readValue 方法可能會更方便。 這樣做可以避免我們在測試中指定冗長的 JSON 輸入。
在本教程中,我們將學習如何使用 Mockito 實現這一點。
2. Maven 依賴
首先,作為 Maven 依賴,我們將使用 mockito-core 和 jackson-databind:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
<type>bundle</type>
</dependency>3. 一個 ObjectMapper 示例
讓我們考慮一個簡單的 Flower 類:
public class Flower {
private String name;
private Integer petals;
public Flower(String name, Integer petals) {
this.name = name;
this.petals = petals;
}
// default constructor, getters and setters
}假設我們有一個用於驗證 JSON 字符串表示的 Flower 對象類。它接受 ObjectMapper 作為構造函數參數——這使得我們稍後輕鬆進行模擬:
public class FlowerJsonStringValidator {
private ObjectMapper objectMapper;
public FlowerJsonStringValidator(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public boolean flowerHasPetals(String jsonFlowerAsString) throws JsonProcessingException {
Flower flower = objectMapper.readValue(jsonFlowerAsString, Flower.class);
return flower.getPetals() > 0;
}
}接下來,我們將使用 Mockito 來編寫驗證邏輯的單元測試。
4. 使用 Mockito 進行單元測試
讓我們首先設置我們的測試類。我們可以輕鬆地創建一個 Mock 對象來模擬 ObjectMapper,並將它作為構造參數傳遞給 FlowerStringValidator 類:
@ExtendWith(MockitoExtension.class)
public class FlowerJsonStringValidatorUnitTest {
@Mock
private ObjectMapper objectMapper;
private FlowerJsonStringValidator flowerJsonStringValidator;
@BeforeEach
public void setUp() {
flowerJsonStringValidator = new FlowerJsonStringValidator(objectMapper);
}
...
}請注意,我們在測試中使用的是 JUnit 5,因此我們已使用 @ExtendWith(MockitoExtension.class) 註解了我們的測試類。
現在我們已經準備好 ObjectMapper 模擬對象,讓我們編寫一個簡單的測試:
@Test
public void whenCallingHasPetalsWithPetals_thenReturnsTrue() throws JsonProcessingException {
Flower rose = new Flower("testFlower", 100);
when(objectMapper.readValue(anyString(), eq(Flower.class))).thenReturn(rose);
assertTrue(flowerJsonStringValidator.flowerHasPetals("this can be a very long json flower"));
verify(objectMapper, times(1)).readValue(anyString(), eq(Flower.class));
}由於我們正在模擬 ObjectMapper,因此可以忽略其輸入並專注於其輸出,該輸出隨後傳遞給實際的驗證邏輯。正如您所看到的,我們不需要指定有效的 JSON 輸入,這在實際場景中可能非常冗長且難以處理。
5. 結論
在本文中,我們學習瞭如何模擬(mock)ObjectMapper 以創建高效的測試用例。