如何对自定义 Jackson JsonSerializer 进行单元测试?

Posted

技术标签:

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

我写了以下JsonSerializer 让Jackson 将整数数组序列化为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。我做错了什么?

【问题讨论】:

【参考方案1】:

你需要flush()生成器

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

【讨论】:

***.com/a/37001410/2428562 这个答案信息量更大【参考方案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() 再次通过。

以上是关于如何对自定义 Jackson JsonSerializer 进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用快速编码根据特定的排序顺序对自定义对象进行排序

如何使用 NSKeyedArchiver 对自定义类进行编码和解码

如何使用喷雾对自定义对象进行 jsonize 处理?

如何对自定义 AJAX 事件进行单元测试

如何在 TensorFlow 中使用 Hugging Face Transformers 库对自定义数据进行文本分类?

如何在 prestashop 1.7 中对自定义页面进行 ajax 请求