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)
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With