Java 如何使用 Jackson 获取 JsonProcessingException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26716020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 03:08:44  来源:igfitidea点击:

How to get a JsonProcessingException using Hymanson

javajsonHymanson

提问by bitoiu

Might be a strange question but indeed I would like to achieve a a bit more coverage on my tests and although I coded against a JsonProcessingExceptionI can't create a payload that generates this exception, maybe because Hymanson is quite smart and converts everything to a string, and even for bad strings it goes around the JSON specs. My problem is that Hymanson is quite good :)

可能是一个奇怪的问题,但确实我想在我的测试中实现更多覆盖,尽管我针对 a 进行编码,但我JsonProcessingException无法创建生成此异常的有效负载,也许是因为 Hymanson 非常聪明并将所有内容转换为字符串,甚至对于坏字符串,它也遵循 JSON 规范。我的问题是Hyman逊很好:)

I basically want a payload that when I run this, it break with JsonProcessingException:

我基本上想要一个有效负载,当我运行它时,它会中断JsonProcessingException

String jsonPayload = objectMapper.writeValueAsString(payload);

I've tried some like:

我试过一些像:

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

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

I'm not fussed with the type, so feel free to suggest another one. An empty object for example, throws JsonMappingExceptionand I already catch that one as well.

我对这种类型并不大惊小怪,所以请随意推荐另一种。例如,抛出一个空对象JsonMappingException,我也已经抓住了那个对象。

回答by Lee Passey

I wanted to do the same thing, and eventually accomplished it by using the Mockito "spy" function, which wraps a real object with a mock object. All calls to the mock object get forwarded to the real object, except those you are trying to mock. For example:

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

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

All usages of omwill be handled by the underlying ObjectMapper instance until an instance of ErrorObjectgets passed in, at which point the JsonProcessingExceptionwill be thrown.

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

The newJsonProcessingExceptionis created as an anonymous class, as it is a protected class and only a sub-class can be instantiated.

newJsonProcessingException创建为匿名类,因为它是受保护的类,并且只能实例化子类。

回答by Liam Williams

You could use something like this:

你可以使用这样的东西:

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

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

Which results in a JsonProcessingExceptionwith message Direct self-reference leading to cycle (through reference chain: ClassThatHymansonCannotSerialize["self"])

这导致JsonProcessingException带有消息Direct self-reference leading to cycle (through reference chain: ClassThatHymansonCannotSerialize["self"])

回答by Hazel Troost

Building off of Liam's answer, mocking the toString()method with a cycle also causes Hymanson to break.

基于 Liam 的答案,toString()用循环嘲笑该方法也会导致 Hymanson 崩溃。

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

EDIT: It's way easier than that. A Mockito mock will always throw it. o.o;;

编辑:这比那容易得多。Mockito 模拟总是会抛出它。哦;;

回答by Mike Mathieson

For me if a class has no public fields/methods writeValueAsString will throw a JsonMappingException (no serializer found for class...)

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

private static class ClassThatHymansonCannotSerialize {}

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

回答by Julien

following on @Mike.Mathieson answer

关注@Mike.Mathieson 的回答

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

public class HymansonTest {

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

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

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

note that this test won't work if the ObjectMapper have been configured to disable SerializationFeature.FAIL_ON_EMPTY_BEANS, e.g.

请注意,如果 ObjectMapper 已配置为 disable SerializationFeature.FAIL_ON_EMPTY_BEANS,则此测试将不起作用,例如

new ObjectMapper()
    .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
    .writeValueAsString(new Object());

回答by senseiwu

Trying to mock using mock(ObjectMapper.class)will invariably result in Checked exception is invalid for this method!as it is not possible to throw checked exception (JsonProcessingExceptionextends IOException). Creating a self referencing value object like other answers suggested could be too convoluted for many cases and looks like a hack.

尝试模拟 usingmock(ObjectMapper.class)总是会导致Checked 异常对于此方法无效!因为不可能抛出已检查的异常(JsonProcessingExceptionextends IOException)。创建一个像其他建议的答案一样的自引用值对象在许多情况下可能过于复杂,看起来像一个黑客。

The easiest way I found is to extend ObjectMapperand then use that in your test method. You should pass the subclass to SUT

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

@Test
public void buildJsonSwallowsJsonProcessingException() {

    class MyObjectMapper extends ObjectMapper {
        @Override
        public String writeValueAsString(Object value)
                throws com.fasterxml.Hymanson.core.JsonProcessingException {
            throw new com.fasterxml.Hymanson.core.JsonProcessingException("Forced error") {};
        }
    }

    ObjectMapper objectMapper = new MyObjectMapper();

    SUTBean sutbean = new SUTBean(objectMapper);

    sutbean.testMethod();

    assertTrue(expected, actual);
}

回答by heug

just in case this may help someone, when i was unit testing for a JsonProcessingException i kept getting this error:

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

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

this was my code

这是我的代码

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

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

i found out i just needed to add "{}" as such

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

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