How to get a JsonProcessingException using Jackson

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 JsonProcessingException I can't create a payload that generates this exception, maybe because Jackson is quite smart and converts everything to a string, and even for bad strings it goes around the JSON specs. My problem is that Jackson is quite good :)

I basically want a payload that when I run this, it break with 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 JsonMappingException and I already catch that one as well.


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:

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

All usages of om will be handled by the underlying ObjectMapper instance until an instance of ErrorObject gets passed in, at which point the JsonProcessingException will be thrown.

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


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

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


You could use something like this:

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

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

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


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

private static class ClassThatJacksonCannotSerialize {}

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

following on @Mike.Mathieson answer

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());
    }
}

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/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.

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