【问题标题】:How to trigger JsonProcessingException for Java Unit Test?如何触发 Java 单元测试的 JsonProcessingException?
【发布时间】:2020-02-13 20:10:45
【问题描述】:

我在一个名为“HttpResponseHelper”的类中有一个方法,当它抛出 JsonProcessingException 时,我试图对其进行单元测试,但我很难做到这一点:

 private static void populateHTTPResponseWithData(ObjectNode httpResponse)
    {
        ObjectMapper mapper = new ObjectMapper();
        responseMapData.keySet().forEach(item -> {
            try
            {
                httpResponse.put(item, mapper.writeValueAsString(responseMapData.get(item)));
            }
            catch (JsonProcessingException e)
            {
                LOGGER.error("Json Processing Exception", e);
            }
        });
    }

httpResponse 参数是 ObjectNode 类型(Jackson 库),然后在方法主体内从 ObjectMapper 类创建一个映射器对象。

resonseMapData 是来自名为“MessageProcessResults”的类的 ConcurrentHashMap>。它看起来像这里它循环通过 keySet 并在 httpResponse 参数内插入键值对的字符串。

我尝试在 mapper 上使用 mockito 来返回格式错误的 JSON,但它看起来像将值写入 String 并且每次都通过。

有没有人有任何建议或者有一个简单的方法可以做到这一点?感谢您花时间阅读这个问题并可能帮助我:D

【问题讨论】:

  • 这个方法从不抛出JsonProcessingException,它会捕获它并只记录结果,如果你将throw e放在你的catch块中它也会抛出它,但它不会继续处理发生异常时,responseMapData 中的其他项目。
  • 我不知道你为什么需要测试它;我假设只是为了获得 100% 的 catch 块覆盖率,但您可能不会测试日志记录是否发生。最好不要担心它。但是您应该注入 ObjectMapper 而不是创建一个,然后您可以在测试中注入一个模拟映射器,并在调用 writeValueAsString 时将其抛出。

标签: java unit-testing jackson jsonexception


【解决方案1】:

您还可以为您的测试扩展JsonProcessingException

private static class MockJsonProcessingException extends JsonProcessingException {
  public MockJsonProcessingException(String message) {
    super(message);
  }
}

然后在你的测试中:

var exception = new MockJsonProcessingException("Because of protected constructors");
when(objectMapper.writeValueAsString(thing)).thenThrow(exception);

编辑:请注意,这假设您正在使用依赖注入并将模拟 ObjectMapper 注入到您的对象中,这是使此案例可测试所必需的。

【讨论】:

    【解决方案2】:

    @HarryQ 答案不起作用,因为 JsonProcessingException 有一个包保护的构造函数。

    对于那些抛出这个的方法,您可以使用 InputCoercionException。它从 JsonProcesssingException 扩展而来,并允许类似丑陋的东西,是的,我知道,但它有效:

    when(mockObjectMapper.writeValueAsString(any())).thenThrow(new InputCoercionException(null, "my mock exception", null, null));
    

    【讨论】:

      【解决方案3】:

      当您进行单元测试时,您不会关注底层代码如何创建异常,而是您的代码如何处理此类异常。在这方面,您可以模拟ObjectNode 对象,并要求它在调用put 方法时抛出异常。

       @Test
      public void someTest(){
          Object mockObject = Mockito.mock(ObjectNode.class);
          Mockito.when(mockObject.put()).thenThrow(new JsonProcessingException ("my mock exception"));
          functionUndertest(mockObject); //this is where you inject your mock function. In your case you are expecting a error message to be printed.
      }
      

      【讨论】:

      • 这不起作用,因为 JsonProcessingException 有一个包保护的构造函数。对于那些抛出这个的方法,您可以使用 InputCoercionException。它从 JsonProcesssingException 扩展并允许类似的东西。丑陋,是的,我知道,但它有效:when(mockObjectMapper.writeValueAsString(any())).thenThrow(new InputCoercionException(null, "my mock exception", null, null));
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      • 2020-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多