Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test a custom Jackson JsonSerializer?

I wrote the following JsonSerializer to let Jackson serialize an array of integers into JSON:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

public class TalkIdsSerializer extends JsonSerializer<TalkIds> {

    /**
     * Serializes a TalkIds object into the following JSON string:
     * Example: { "talk_ids" : [ 5931, 5930 ] }
     */
    @Override
    public void serialize(TalkIds talkIds, JsonGenerator jsonGenerator, 
        SerializerProvider provider)
            throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeArrayFieldStart(TalkIds.API_DICTIONARY_KEY);
        for (Integer talkId : talkIds.getTalkIds()) {
            jsonGenerator.writeNumber(talkId);
        }
        jsonGenerator.writeEndArray();
        jsonGenerator.writeEndObject();
    }

}

The class is used here:

@JsonSerialize(using = TalkIdsSerializer.class)
public class TalkIds { /* ...  */ }

I want test the behavior of the serializer and came up with the following:

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import org.junit.Before;
import org.junit.Test;    
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class TalkIdsSerializerTest {

    protected final ArrayList<Integer> TALK_IDS = 
        new ArrayList<>(Arrays.asList(5931, 5930));

    protected TalkIdsSerializer talkIdsSerializer;

    @Before
    public void setup() throws IOException {
        talkIdsSerializer = new TalkIdsSerializer();
    }

    @Test
    public void testSerialize() throws IOException {
        StringWriter stringWriter = new StringWriter();
        JsonGenerator jsonGenerator = 
            new JsonFactory().createGenerator(stringWriter);
        TalkIds talkIds = new TalkIds();
        talkIds.add(TALK_IDS);
        talkIdsSerializer.serialize(talkIds, jsonGenerator, null);
        String string = stringWriter.toString(); // string is ""
        assertNotNull(string);
        assertTrue(string.length() > 0);
        stringWriter.close();
    }

}

However, nothing is written to the StringWriter. What am I doing wrong?

like image 750
JJD Avatar asked Nov 24 '15 11:11

JJD


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 @JsonTest?

The @JsonTest annotation ensures to auto-configure a Spring TestContext with only a subset of Spring Beans required to test the JSON serialization. Anything related to our web-layer or persistence-layer is not part of this sliced application context.

How do I add custom deserializer to Jackson?

To create a custom deserializer, we need to create a class extending StdDeserializer and then override its deserialize() method. We can use custom deserializer either by registering with ObjectMapper or annotating class with @JsonDeserialize . Now find the JSON used in our demo.


2 Answers

You need to flush() the generator

Method called to flush any buffered content to the underlying target (output stream, writer), and to flush the target itself as well.
http://fasterxml.github.io/jackson-core/javadoc/2.1.0/com/fasterxml/jackson/core/JsonGenerator.html#flush()

like image 175
Murat Karagöz Avatar answered Nov 25 '22 04:11

Murat Karagöz


I had a similar requirement, to test a custom serializer. I used objectMapper to get the string directly(since you have already annotated TalkIds with JsonSerialize). You can get the json string from the object as follows

String json = new ObjectMapper().writeValueAsString(talkIds)
like image 45
shivdim Avatar answered Nov 25 '22 04:11

shivdim