Suisse
Suisse

Reputation: 3613

How can I write a JUnit-Test for custom Jackson Serializer?

I wanted to test my serializer which parses my java object to a json object. This is my Serializer class:

public class CountryCodeSerializer extends JsonSerializer<CountryCode> {

    @Override
    public void serialize(CountryCode value, JsonGenerator generator, SerializerProvider provider)
            throws IOException, JsonProcessingException {

        if (value == null) {
            generator.writeString("{}");
        } else {
            generator.writeString(value.toString());
        }
    }

}

My test looks like this:

    @Before
        public void setUp() throws Exception {
            stringJson = new StringWriter();
            generator = new JsonFactory().createGenerator(stringJson);
            provider = new ObjectMapper().getSerializerProvider();
            countryCode = CountryCode.parse("us");
        }

        @Test
        public void parsingNullReturnsNull() throws Exception {
            assertThat(countryCodeSerializer.serialize(countryCode, generator, provider)).isEqualTo("{'countrycode':'us'}); //this doesn't work, since serialize() is void

//countryCodeSerializer.serialize(countryCode, generator, provider); //this throws an java.lang.NullPointerException
        }

So how can I test my serializer? I tried other answers to similar questions, but nothing worked for me.

I use the serializer like this in my other clases:

@JsonSerialize(using = CountryCodeSerializer.class)
    private CountryCode countryCode;

Upvotes: 3

Views: 5054

Answers (3)

Suisse
Suisse

Reputation: 3613

Ok thank you for your answers. I got it now this way and it works fine:

I changed my serializer a little bit:

public class CountryCodeSerializer extends JsonSerializer<CountryCode> {
       @Override
        public void serialize(CountryCode value, JsonGenerator generator, SerializerProvider provider)
                throws IOException, JsonProcessingException {

            if (null == value) {
                throw new IllegalArgumentException("CountryCode is null");
            } else {
                generator.writeString(value.toString());
            }
        }        
    }

And here are my two tests:

public class CountryCodeSerializerTest {

    private CountryCodeSerializer countryCodeSerializer;
    private JsonGenerator jsonGenerator;

    @Before
    public void setUp() throws Exception {
        countryCodeSerializer = new CountryCodeSerializer();
        jsonGenerator = mock(JsonGenerator.class);
    }

    @Test
    public void testNullCountryCodeThrowsIllegalArgumentException() throws Exception {
        try {
            countryCodeSerializer.serialize(null, jsonGenerator, null);
            fail("An IllegalArgumentException should have been thrown.");
        } catch (IllegalArgumentException e) {
            //ok
        }
    }

    @Test
    public void testCountryCodeConvertedToJsonString() throws Exception {
        countryCodeSerializer.serialize(CountryCode.parse("us"), jsonGenerator, null);
        verify(jsonGenerator).writeString("us");
    }
}

Upvotes: 1

andrucz
andrucz

Reputation: 2021

This can be achieved by creating a custom JsonGenerator that stores what is written to it.

class TestJsonGenerator extends JsonGenerator {

    private StringBuilder stringBuilder = new StringBuilder();

    ...

    @Override
    public void writeString(String text) {
        stringBuilder.append(text);
    }

    public String getText() {
        return stringBuilder.toString();
    }

}

Then you verify the generated content, without needing to check all the calls to writeString that were made:

TestJsonGenerator testGenerator = new TestJsonGenerator();
serializer.serialize(countryCode, testGenerator, provider);

assertThat(testGenerator.getText()).isEqualsTo("{ \"foo\": \"bar\" }");

Upvotes: 0

Adriaan Koster
Adriaan Koster

Reputation: 16209

Something like this:

@Mock 
private JsonGenerator generator;

@Test
public void testInstanceWithValue() {
    //SETUP
    String expectedValue = "test value";
    CountryCode value = mock(CountryCode.class);
    when(value.toString()).thenReturn(expectedValue);

    // CALL
    CountryCodeSerializer instance = new CountryCodeSerializer(value, generator, null);

    // VERIFY
    verify(generator).writeString(expectedValue);
}

@Test
public void testInstanceWithNull() {
    //SETUP
    CountryCode value = null;

    // CALL
    CountryCodeSerializer instance = new CountryCodeSerializer(value, generator, null);

    // VERIFY
    verify(generator).writeString("{}");
}

Upvotes: 0

Related Questions