ObjectMapperreadValue()メソッドのモック
1. 概要
ジャクソンでJSONの逆シリアル化を含むコードを単体テストする場合、 ObjectMapper#readValueメソッドをモックする方が簡単な場合があります。 そうすることで、テストで長いJSON入力を指定する必要がなくなります。
このチュートリアルでは、Mockitoを使用してこれを実現する方法を説明します。
2. Mavenの依存関係
まず、Mavenの依存関係として、mockito-coreとjackson-databindを使用します。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</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
}
そして、FlowerオブジェクトのJSON文字列表現を検証するためのクラスがあるとします。 コンストラクター引数として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);
}
...
}
テストではJUnit5 を使用しているため、テストクラスに @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 をモックして、その周りに効率的なテストケースを提供する方法を見ました。 最後に、コードはGitHubのにあります。