如何使用Jackson获取JsonProcessingException

bit*_*oiu 22 java json jackson

可能是一个奇怪的问题,但实际上我想在我的测试中实现更多的覆盖,虽然我编写了一个JsonProcessingException我无法创建生成此异常的有效负载,可能是因为Jackson很聪明并将所有内容转换为字符串,甚至对于糟糕的字符串,它也适用于JSON规范.我的问题是杰克逊非常好:)

我基本上想要一个有效载荷,当我运行它,它打破JsonProcessingException:

String jsonPayload = objectMapper.writeValueAsString(payload);
Run Code Online (Sandbox Code Playgroud)

我试过一些像:

HashMap<String, String> invalidJSONPayload= new HashMap<>();

invalidJSONPayload.put("021",021);
invalidJSONPayload.put("---",021);
invalidJSONPayload.put("~",021);
Run Code Online (Sandbox Code Playgroud)

我不喜欢这种类型,所以请随意提出另一个.例如,一个空对象抛出JsonMappingException,我也已经抓住了那个.

小智 13

如果将两个字段映射到同一属性,您可能会收到 JsonProcessingException。

class InvalidObject {
    @JsonProperty("s")
    private String x = "value1";
    
    @JsonProperty("s")
    private String y = "value2";
}
Run Code Online (Sandbox Code Playgroud)

异常消息是“代表属性“s”的多个字段:...”


小智 12

我想做同样的事情,最终通过使用Mockito"间谍"函数完成它,该函数用模拟对象包装一个真实对象.对模拟对象的所有调用都转发到真实对象,除了那些你试图模拟的对象.例如:

ObjectMapper om = Mockito.spy(new ObjectMapper());
Mockito.when( om.writeValueAsString(ErrorObject.class)).thenThrow(new JsonProcessingException("") {});
Run Code Online (Sandbox Code Playgroud)

所有用法都om将由底层ObjectMapper实例处理,直到ErrorObject传入一个gets 实例,此时JsonProcessingException将抛出它.

new JsonProcessingException是作为匿名类创建的,因为它是受保护的类,只能实例化一个子类.

  • 这将抛出 `Checked exception is invalid for this method!` 并且不起作用 (3认同)
  • JsonProcessingException 构造函数具有 protected 访问修饰符。因此,无法通过调用 `new JsonProcessingException("")` 创建 (3认同)

Lia*_*ams 12

你可以使用这样的东西:

private static class ClassThatJacksonCannotSerialize {
    private final ClassThatJacksonCannotSerialize self = this;

    @Override
    public String toString() {
        return self.getClass().getName();
   }
}
Run Code Online (Sandbox Code Playgroud)

这导致了一条JsonProcessingException消息Direct self-reference leading to cycle (through reference chain: ClassThatJacksonCannotSerialize["self"])


小智 7

对我来说,如果一个类没有公共字段/方法,writeValueAsString将抛出一个JsonMappingException(没有为类找到序列化器...)

private static class ClassThatJacksonCannotSerialize {}

private void forceProcessingException() {
    ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
}
Run Code Online (Sandbox Code Playgroud)


Jul*_*ien 7

以下@ Mike.Mathieson答案

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

public class JacksonTest {

    @Test(expected = JsonProcessingException.class)
    // actually throws an InvalidDefinitionException (which extends JsonProcessingException)
    public void encodeThrowsException() throws JsonProcessingException {
        new ObjectMapper().writeValueAsString(new Object());
    }
}
Run Code Online (Sandbox Code Playgroud)

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/exc/InvalidDefinitionException.html

请注意,如果ObjectMapper已配置为disable SerializationFeature.FAIL_ON_EMPTY_BEANS,则该测试将无法进行,例如

new ObjectMapper()
    .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
    .writeValueAsString(new Object());
Run Code Online (Sandbox Code Playgroud)


Haz*_*ost 5

以利亚姆的答案为toString()基础,用一个循环模拟该方法也会导致杰克逊破产。

@Test
public void forceJsonParseException() {
    try {
        Object mockItem = mock(Object.class);
        when(mockItem.toString()).thenReturn(mockItem.getClass().getName());
        new ObjectMapper().writeValueAsString(mockItem);
        fail("did not throw JsonProcessingException");
    } catch (JsonProcessingException e) {
        //pass
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:比这更容易。Mockito模拟将始终将其抛出。oo ;;