Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit-test Jackson JsonSerializer and JsonDeserializer

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)

like image 849
gue Avatar asked Feb 14 '14 18:02

gue


People also ask

How do I unit test a JSON converter?

Thus, to properly unit-test your converter, you need to advance the reader to the first token of the c# object you are trying to read, e.g. like so: JsonReader reader = new JsonTextReader(new StringReader(json)); while (reader. TokenType == JsonToken.

What is Jackson deserializer?

Jackson is a powerful and efficient Java library that handles the serialization and deserialization of Java objects and their JSON representations. It's one of the most widely used libraries for this task, and runs under the hood of many other frameworks.

How do I create a custom JSON deserializer?

The @JsonDeserialize annotation is used to declare custom deserializer while deserializing JSON to Java object. We can implement a custom deserializer by extending the StdDeserializer class with a generic type Employee and need to override the deserialize() method of StdDeserializer class.

How does JSON deserialize work Java?

Deserialization – Read JSON using Gson Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished.


1 Answers

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.

like image 133
Robert Bain Avatar answered Sep 29 '22 14:09

Robert Bain