【问题标题】:How to unit test a custom Jackson JsonSerializer?如何对自定义 Jackson JsonSerializer 进行单元测试?
【发布时间】:2016-02-26 20:10:53
【问题描述】:

我写了以下JsonSerializerJackson 将整数数组序列化为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();
    }

}

这里使用的类:

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

我想测试序列化程序的行为并提出以下建议:

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();
    }

}

但是,什么都没有写入StringWriter。我做错了什么?

【问题讨论】:

    标签: java json junit jackson jsonserializer


    【解决方案1】:

    你需要flush()生成器

    调用方法将任何缓冲内容刷新到底层目标(输出流、写入器),以及刷新目标本身。
    http://fasterxml.github.io/jackson-core/javadoc/2.1.0/com/fasterxml/jackson/core/JsonGenerator.html#flush()

    【讨论】:

    【解决方案2】:

    我有类似的要求,要测试自定义序列化程序。我使用 objectMapper 直接获取字符串(因为您已经使用 JsonSerialize 注释了 TalkIds)。您可以从对象中获取json字符串,如下所示

    String json = new ObjectMapper().writeValueAsString(talkIds)
    

    【讨论】:

    • 这是迄今为止最简单的 JSON 序列化单元测试方法。谢谢。
    【解决方案3】:

    对我来说flush()什么都没有改变,所以我改变了测试的方式,按照http://www.baeldung.com/jackson-custom-serialization

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import java.io.StringWriter;
    
    //...
    
        @Test
        public void serialize_custom() throws Exception {
            ObjectMapper objectMapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addSerializer(MyCustomSerializer.class, myCustomSerializer);
            objectMapper.registerModule(module);
            StringWriter stringWriter = new StringWriter();
    
            TalkIds talkIds = new TalkIds();
            talkIds.add(TALK_IDS);
    
            objectMapper.writeValue(stringWriter,wi);
            assertTrue(stringWriter.toString().length() > 3);
        }
    

    【讨论】:

    • 欢迎checkout the code。请注意,该 API 目前处于离线状态。我可能会模拟 API 响应,以便让 testThatRealServerIsReachable() 再次通过。
    猜你喜欢
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    相关资源
    最近更新 更多