How to unit-test Jackson JsonSerializer and JsonDeserializer
jackson, unit-testing
Solution
JsonSerializer
The example is serialising a `LocalDateTime` but this can replaced by the required type.
@Test
public void serialises_LocalDateTime() throws JsonProcessingException, IOException {
Writer jsonWriter = new StringWriter();
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(jsonWriter);
SerializerProvider serializerProvider = new ObjectMapper().getSerializerProvider();
new LocalDateTimeJsonSerializer().serialize(LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0), jsonGenerator, serializerProvider);
jsonGenerator.flush();
assertThat(jsonWriter.toString(), is(equalTo("\"2000-01-01T00:00:00\"")));
}
JsonDeserializer
The example is deserialising a `Number` but this can replaced by the required type.
private ObjectMapper mapper;
private CustomerNumberDeserialiser deserializer;
@Before
public void setup() {
mapper = new ObjectMapper();
deserializer = new CustomerNumberDeserialiser();
}
@Test
public void floating_point_string_deserialises_to_Double_value() {
String json = String.format("{\"value\":%s}", "\"1.1\"");
Number deserialisedNumber = deserialiseNumber(json);
assertThat(deserialisedNumber, instanceOf(Double.class));
assertThat(deserialisedNumber, is(equalTo(1.1d)));
}
@SneakyThrows({JsonParseException.class, IOException.class})
private Number deserialiseNumber(String json) {
InputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
JsonParser parser = mapper.getFactory().createParser(stream);
DeserializationContext ctxt = mapper.getDeserializationContext();
parser.nextToken();
parser.nextToken();
parser.nextToken();
return deserializer.deserialize(parser, ctxt);
}
UPDATE
When upgrading to jackson 2.9.3 I received a `NullPointerException` in `DeserializationContext` in `isEnabled(MapperFeature feature)` when deserialising strings to numbers because `new ObjectMapper()` initialises `_config` to `null`.
To get around this, I used this SO answer to spy on the `final` class `DeserializationContext`:
DeserializationContext ctxt = spy(mapper.getDeserializationContext());
doReturn(true).when(ctxt).isEnabled(any(MapperFeature.class));
I feel there must be a better way, so please comment if you have one.
Problem
I've written custom JsonSerializer and JsonDeserializer for my app. Now I want to write some unit-tests for them. How should a clean test case look like? Are there some clean examples out there? (clean means no dependencies to other frameworks or libraries)