1

I have a class as shown below:

@Getter
@Setter
public class User{

    @Autowired
    Logger log;

    private String name;
    private String age;

    public String toJson(){
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = null;
        try{
            jsonString = objectMapper.writeValueAsString(this);
        }catch(JsonProcessingException jsnEx){
            log.writeErr(" Error while parsing the Json" + jsnEx.getMessage());
        }
        return jsonString;
    }
}

Now I am trying to write a unit test case for this where I can throw exception and unit test the catch clause using Mockito but I am not able to mock it. I have noticed that object mapper class internally converting everything to string even if I set name and age to null. Can anyone please help me with this?

3
  • Maybe make toJson accept ObjectMapper and mock it? Or pass it to User. Though this look like a bad decision since your class now has more than on responsibility violating Single Responsibility Principle. Commented Jan 10, 2022 at 14:52
  • Why do you instanciate ObjectMapper in toJson? ObjectMapper Intanciation in the function take time if your methode is called lot of times. And make the code pretty hard to unit test. Commented Jan 10, 2022 at 14:58
  • Hi @soung yes you are right, I have changed the method to take object mapper instance as an method argument Commented Jan 11, 2022 at 4:38

1 Answer 1

2

Use constructor injection with Spring. This will allow you to inject mocked ObjectMapper in the class, which then you can set behavior in the test. See below.

@Getter
@Setter
public class User{

    private String name;
    private String age;
    
    private final Logger log;
    private final ObjectMapper objectMapper;
    
    public User(Logger log, ObjectMapper objectMapper){
        this.log = log;
        this.objectMapper = objectMapper;
    }

    public String toJson(){
        String jsonString = null;
        try{
            jsonString = objectMapper.writeValueAsString(this);
        }catch(JsonProcessingException jsnEx){
            log.writeErr(" Error while parsing the Json" + jsnEx.getMessage());
        }
        return jsonString;
    }
}


// Test

@Before
public setup(){
    @Mock
    Logger log;
    
    @Mock
    ObjectMapper objectMapper;        
    testObject = new User(log, objectMapper);
}

@Test
public test_toJson(){
    // given
    when(objectMapper.writeValueAsString(any())).thenThrow(new JsonProcessingException("Fake exception"))
    // when
    testObject.toJson()
}
Sign up to request clarification or add additional context in comments.

3 Comments

Wouldn't your test always fail as the method under test is catching the JsonProcessingException at which point it writes to the log and the method returns null without throwing any exception?
That is correct, i edited the original answer. No need to expect the exception in the Test since its handled by the method. Thanks @Gavin
Hi @Gavin yes it will fail but then you can add a throw statement in your catch block to pass your test case. thanks for pointing out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.