可能是一个奇怪的问题,但实际上我想在我的测试中实现更多的覆盖,虽然我编码了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
,我也已经捕获了那个。
答案 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
请注意,如果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());
}
这是垃圾,高级垃圾:),但它有效,我想与您分享它作为模拟的替代品
再见