如何使用Jackson获取JsonProcessingException

时间:2014-11-03 14:13:24

标签: java json jackson

可能是一个奇怪的问题,但实际上我想在我的测试中实现更多的覆盖,虽然我编码了JsonProcessingException我无法创建产生此异常的有效负载,可能是因为Jackson相当聪明并将所有内容转换为字符串,即使是坏字符串,它也会绕过JSON规范。我的问题是杰克逊非常好:)。

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

String jsonPayload = objectMapper.writeValueAsString(payload);

我尝试了一些:

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

invalidJSONPayload.put("021",021);
invalidJSONPayload.put("---",021);
invalidJSONPayload.put("~",021);

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

10 个答案:

答案 0 :(得分:10)

我想做同样的事情,并最终通过使用Mockito&#34;间谍&#34; function,用一个模拟对象包装一个真实对象。对模拟对象的所有调用都转发到真实对象,除了那些你试图模拟的对象。例如:

ObjectMapper om = Mockito.spy(new ObjectMapper());
Mockito.when( om.writeValueAsString(ErrorObject.class)).thenThrow(new JsonProcessingException("") {});

om的所有用法都将由底层ObjectMapper实例处理,直到ErrorObject的实例被传入,此时将抛出JsonProcessingException

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

答案 1 :(得分:8)

您可以使用以下内容:

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

    @Override
    public String toString() {
        return self.getClass().getName();
   }
}

这会产生JsonProcessingException消息Direct self-reference leading to cycle (through reference chain: ClassThatJacksonCannotSerialize["self"])

答案 2 :(得分:6)

对我来说,如果一个类没有公共字段/方法,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);
        }
}

答案 3 :(得分: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
    }
}
编辑:它比这更容易。一个Mockito模拟总会抛出它。 o.o ;;

答案 4 :(得分:4)

关注@ Mike.Mathieson答案

include

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

请注意,如果ObjectMapper已配置为禁用```{r, include = FALSE} # your code to build model ``` ```{r} plot(example) ``` ,例如

,则此测试将无法进行
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());
    }
}

答案 5 :(得分:1)

尝试使用mock(ObjectMapper.class)进行模拟将始终导致此方法的Checked异常无效!!因为无法抛出Checked异常(JsonProcessingException扩展了{{1 }})。在许多情况下,创建像其他建议的答案一样的自引用值对象可能会很费时,而且看起来很像黑客。

我发现最简单的方法是扩展IOException,然后在测试方法中使用它。您应该将子类传递给SUT

ObjectMapper

答案 6 :(得分:1)

我在Jackson Github问题中找到了这个;但这解决了我的问题,我可以抛出JsonProcessingException。

null

现在如何在代码中使用它

需要测试此方法

 @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
}
}

这就是我测试JsonProcessingException的方式

public String geResponse(MyObject myObject) {

try {
  return objectMapper.writeValueAsString(myObject);
} catch (JsonProcessingException e) {
  log.error("Service response JsonParsing error {} ", e.getMessage());
  return "Validation Service response JsonParsing error {} "+ e.getMessage();
 }
}

我希望这会有所帮助!

答案 7 :(得分:0)

以防万一这可能对某人有所帮助,当我在对JsonProcessingException进行单元测试时,我不断收到此错误:

JsonProcessingException has protected access in com.fasterxml.jackson...

这是我的代码

// error is on the below line
JsonProcessingException e = new JsonProcessingException("borked");

doThrow(e).when(classMock).methodToMock(any(), any());

我发现我只需要添加“ {}”

JsonProcessingException e = new JsonProcessingException("borked") {};

答案 8 :(得分:0)

在 getter 中抛出异常以模拟 JsonProcessingException。

public static class TestData {
    public String getEx() throws JsonProcessingException { throw new JsonParseException(null, "test"); }
}

ObjectMapper().writeValueAsString(new TestData());

答案 9 :(得分:0)

我被问到这个问题,因为我和提问者有相同的目标:

<块引用>

可能是一个奇怪的问题,但确实我想实现一点 更多关于我的测试的报道

恕我直言,Mockito 解决方案更优雅,不会引起误解,但我向一位同事提出挑战,要求他找到另一种解决方案,他做到了。这是解决方案:

@Test
@DisplayName("Object To Json KO")
void objectToJsonKOTest() {
    KafkaMessageDTO o = new KafkaMessageDTO() {
        @Override
        public String getAuthCode() {
            int a = 2/0;
            return super.getAuthCode();
        }
    };

    String s = mapper.writeValueAsString(o);
    Assertions.assertTrue(s.isEmpty());
}

这是垃圾,高级垃圾:),但它有效,我想与您分享它作为模拟的替代品

再见