JSOnProcessingException的单元测试



我想编写一个单元测试来测试JSONProcessingException。该例外可能会在线上发生:mapper.writeValueasString()。

public void myMethod(Args...) {
        try {
               ObjectMapper mapper = new ObjectMapper();
                mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
                Document.parse(mapper.writeValueAsString(testObject)));
            }
        } catch (JsonProcessingException e) {
            log.error("Error parsing the object to json string. ", e);
        } 
}

这是我的单位测试:

public class Test {
    @Mock
    private ObjectMapper              mapper;
    @InjectMocks
    ClassUnderTest            sut;
    @Test
    public void testJsonProcessingException() throws     JsonProcessingException {
        when(mapper.writeValueAsString(Mockito.any())).thenThrow(new     JsonProcessingException("Error parsing the object to json string. "){
            private static final long serialVersionUID = 1L;});
        sut.myMethod(args...);
    }
}

问题是我所模拟的映射器将不会被使用(我会不会获得不必要的oblito stubbings失败),因为映射器在方法内再次初始化。我如何使用Mockito进行单元测试?

mapper不是测试实例的字段/依赖性。
它是该方法中创建的局部变量:

 public void myMethod() {
        try {
            ObjectMapper mapper = new ObjectMapper();
         ...
}

所以,@InjectMocks将是无助的。

我可以提出两个替代方案:

1)您可以通过更改方法的签名来传递mapper作为参数:

 public void myMethod(ObjectMapper mapper) {
  ...
 }

这样,您可以将模拟的ObjectMapper作为测试方法的参数传递。

如果经常调用此方法,则通过锅炉板参数可能很烦人,并且使代码不那么可读。

2)另一种方法是通过正在测试的类的构造函数设置ObjectMapper的方法。

public class ClassUnderTest{
   private ObjectMapper objectMapper;
   ...
   public ClassUnderTest(ObjectMapper objectMapper){
      this.objectMapper = objectMapper;
  }
  ...
}

使用objectMapper测试方法并抛出自定义(包装JSONProcessingException),我们需要模拟对象mapper并告诉它进行异常。

这是一个可以解析jsonnode并进行自定义异常的方法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MyService {
    private final ObjectMapper objectMapper;
    public Boolean processSomething(JsonNode jsonNode) {
        Simple simple;
        try {
            simple = objectMapper.readValue(jsonNode.toString(), Simple.class);
        } catch (JsonProcessingException e) {
            throw new CustomServerException(e.getMessage(), e);
        }
        return true;
    }
}

测试此方法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.my.path.MyService;
import org.assertj.core.api.Assertions;
import org.mockito.Mockito;
import org.testng.annotations.Test;
public class TestMyService {
    // To test the method for the CustomServerException,
    // we need to mock the ObjectMapper to throw the JsonProcessingException:
    @Test
    void testProcessSomething_JsonProcessingException() {
        // using a mock ObjectMapper to force a JsonProcessingException to be thrown
        ObjectMapper mockMapper = Mockito.mock(ObjectMapper.class);
        MyService serviceWithMockMapper = new MyService(mockMapper);
        CustomServerException thrown = assertThrows(CustomServerException.class, () -> {
            when(mockMapper.readValue(jsonNode.toString(), Simple.class)).thenThrow(JsonProcessingException.class);
            serviceWithMockMapper.processSomething(jsonNode);
        });
        Assertions.assertNotNull(thrown.getMessage());
    }
}

相关内容

  • 没有找到相关文章

最新更新