2014-11-03 143 views
7

可能是一个奇怪的问题,但的确我想在测试中实现更多的覆盖率,尽管我编码为JsonProcessingException我无法创建产生此异常的有效负载,也许是因为杰克逊非常聪明,将所有东西都转换为字符串,即使是坏字符串,它也会绕过JSON规范。我的问题是,杰克逊是相当不错的:)如何使用杰克逊得到JsonProcessingException

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

String jsonPayload = objectMapper.writeValueAsString(payload); 

我已经尝试了一些这样的:

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

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

我不喜欢这种类型,所以随时可以推荐另一种。例如,一个空的对象,抛出JsonMappingException,我也已经抓住了那个。

+1

好了,你可以模拟一个'ObjectMapper'并将其抛出异常,因为ObjectMapper不是最终的 – fge 2014-11-03 14:30:59

+0

这不是嘲笑测试本身,我想重现一个场景,事实上可以发生在正在运行的应用程序的上下文中。也许一个不存在?如果是这样,为什么是例外?感谢你的回答。 – bitoiu 2014-11-03 15:31:37

+1

好吧,我以为你想测试你的代码的行为,如果这个异常被提出,这就是为什么我建议这个 – fge 2014-11-03 15:42:44

回答

7

我想要做同样的事情,并最终通过使用Mockito“间谍”功能完成它,该功能用一个模拟对象封装了一个真实对象。所有对模拟对象的调用都会被转发到真实对象,除了那些您试图模拟的对象。例如:

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

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

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

+0

假设有效载荷对象具有公共getter和setter方法,你可以简单地在有效载荷对象上使用间谍,然后让其中一个getter返回null。 Payload payloadSpy = Mockito.spy(payload); Mockito.doReturn(空)。当(payloadSpy).getField(); String jsonPayload = objectMapper.writeValueAsString(payloadSpy); – pilotg2 2015-10-02 17:14:28

2

你可以使用这样的事情:

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"])导致

1

大厦关闭Liam的回答,用循环嘲讽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 ;;

2

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