gue*_*gue 36 unit-testing jackson
我为我的应用程序编写了自定义JsonSerializer和JsonDeserializer.现在我想为它们编写一些单元测试.
干净的测试用例应该如何?
那里有一些干净的例子吗?
(clean表示不依赖于其他框架或库)
Rob*_*ain 38
JsonSerializer
该示例是序列化a LocalDateTime但可以由所需类型替换.
@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\"")));
}
Run Code Online (Sandbox Code Playgroud)
JsonDeserializer
示例是反序列化a Number但可以用所需类型替换.
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);
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
当升级到jackson 2.9.3时,我将字符串反序列化为数字时收到了NullPointerExceptionin DeserializationContextin isEnabled(MapperFeature feature),因为new ObjectMapper()初始化_config为null.
为了解决这个问题,我使用这个 SO答案来窥探这个final课程DeserializationContext:
DeserializationContext ctxt = spy(mapper.getDeserializationContext());
doReturn(true).when(ctxt).isEnabled(any(MapperFeature.class));
Run Code Online (Sandbox Code Playgroud)
我觉得必须有一个更好的方法,所以如果你有一个,请评论.
bon*_*onh 12
其他答案很好地涵盖了序列化。对于反序列化,我还有其他建议。
如果您的域类具有@JsonDeserialize注释,则默认的ObjectMapper将使用反序列化器,而无需显式注册它。
@JsonDeserialize(using=ExampleDeserializer.class)
public class Example {
private String name;
private BananaStore bananaStore;
public Example(String name, BananaStore bananaStore) {
this.name = name;
this.bananaStore = bananaStore;
}
public String getName() {
return name;
}
public BananaStore getBananaStore() {
return bananaStore;
}
}
Run Code Online (Sandbox Code Playgroud)
并且您的单元测试可以变得更短:
public class ExampleDeserializerTest {
@Test
public void deserialize() throws IOException {
String json = "{\"name\":\"joe\",\"bananas\":16}";
Example example = new ObjectMapper().readValue(json, Example.class);
assertEquals("joe", example.getName());
assertEquals(16, example.getBananaStore().getBananaCount());
}
}
Run Code Online (Sandbox Code Playgroud)
解串器可以像这样进行单元测试:
public class CustomFooDeserializerTest {
private Foo foo;
@Before
public void setUp() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Foo.class, new CustomFooDeserializer());
objectMapper.registerModule(module);
foo = objectMapper.readValue(new File("path/to/file"), Foo.class);
}
@Test
public void shouldSetSomeProperty() {
assertThat(foo.getSomeProperty(), is("valueOfSomeProperty"));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33738 次 |
| 最近记录: |