1. 概述
當進行涉及使用 Jackson 反序列化 JSON 的代碼單元測試時,我們可能會發現模擬 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 進行單元測試
首先,讓我們設置測試類。我們可以輕鬆地模擬 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. 結論
在本文中,我們看到了如何模擬 ObjectMapper 以提供高效的測試用例。