获取 org.mockito.exceptions.base.MockitoException:已检查的异常对此方法无效!即使我抛出了正确的异常

问题描述 投票:0回答:2

获取 org.mockito.exceptions.base.MockitoException: 检查异常对此方法无效!即使我抛出了正确的异常。我正在尝试测试此类 DecileConfigurationJsonConverter。在测试中,我正在测试读取数据库数据时的异常抛出场景。如果它无法读取数据库数据,它会抛出 IOException,并且在模拟中我确实抛出了完全相同的异常,但我收到了上述错误。

  public class DecileConfigurationJsonConverter  implement               AttributeConverter<List<DecileParameter>,String>{
  private static final  ObjectMapper objectMapper = new ObjectMapper();
  @Override
  public List<DecileParameter> convertToEntityAttribute(String dbData) {
      if(dbData==null)
          return null;
      List<DecileParameter> dep = null;
      try
      {
          dep = objectMapper.readValue(dbData,
                  new TypeReference<List<DecileParameter>>() {});
      }
      catch (final IOException e)
      {
          return null;
      }
      return dep;
  }
}

  @RunWith(SpringRunner.class)
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  @AutoConfigureMockMvc
  @ActiveProfiles("dev-test")
  @TestPropertySource(locations = "classpath:application-dev-test.yml")
  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
  public class UtilPackageTestMore {

  @Mock
  ObjectMapper objectMapper;

  private static void setFinalStaticField(Class<?> clazz, String fieldName, Object value)
          throws ReflectiveOperationException {

      Field field = clazz.getDeclaredField(fieldName);
      field.setAccessible(true);

      Field modifiers = Field.class.getDeclaredField("modifiers");
      modifiers.setAccessible(true);
      modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, value);
  }

  @Test
  public void TestDecileConfigurationJsonConverterExceptions() throws Exception
  {
      DecileConfigurationJsonConverter dc= new DecileConfigurationJsonConverter();
      ObjectMapper objecmapper = Mockito.mock(ObjectMapper.class);
      setFinalStaticField(DecileConfigurationJsonConverter.class, "objectMapper", objecmapper);

      List<DecileParameter> attribute = new ArrayList<>();
      attribute.add(new DecileParameter("1","2","3","4","5"));
      Mockito.when(objecmapper.writeValueAsString(attribute)).thenThrow(JsonProcessingException.class);
      String res = dc.convertToDatabaseColumn(attribute);
      assertNull(res);

      //here is the exception got thrown
      Mockito.when(objecmapper.readValue("db data",new TypeReference<List<DecileParameter>>() {})).thenThrow(java.io.IOException.class);
      List<DecileParameter> convertToEntityAttribute = dc.convertToEntityAttribute("db data");
      assertNull(convertToEntityAttribute);

  }   
mockito junit4
2个回答
1
投票

你必须扔一个

Exception
,但你正在扔一个
Class<Exception>
JsonProcessingException.class
返回一个
Class<Exception>
实例。
new JsonProcessingException()
返回一个新的
Exception
实例。你只能扔后者。

Mockito.when(objecmapper.writeValueAsString(attribute))
        .thenThrow(new JsonProcessingException());

但实际上你根本不需要在这里嘲笑任何东西。尽量避免反射。保持测试简单,不要将它们耦合到您的实现中。

public class DecileConfigurationJsonConverter
    implements AttributeConverter<List<DecileParameter>, String> {
  private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

  @Override
  public List<DecileParameter> convertToEntityAttribute(final String dbData) {
      if (dbData==null) return null;
      try
      {
          return OBJECT_MAPPER.readValue(dbData,
                  new TypeReference<List<DecileParameter>>() {});
      }
      catch (final IOException e)
      {
          return null;
      }
  }
}

public class UtilPackageTestMore {

  @Test
  public void TestDecileConfigurationJsonConverterExceptions() throws Exception
  {
      final DecileConfigurationJsonConverter dc = new DecileConfigurationJsonConverter();

      final List<DecileParameter> convertToEntityAttribute = dc.convertToEntityAttribute("INVALID_JSON"); // value can be anything that cannot be deserialized
      assertNull(convertToEntityAttribute);

  }
}   

0
投票

我已经在另一个线程回答了这个问题:

调用

doThrow
抛出已检查的异常时会抛出此异常 来自未在以下位置声明此已检查异常的方法的异常 抛出。

一些选项

1.扔
RuntimeException
而不是
Exception

改变

public class UserAccountException extends Exception {

public class UserAccountException extends RuntimeException {

2. 使用以下替代方案

when(repository.findById(id)).then(ignored -> { throw new UserAccountException("checked"); });

doAnswer(ignored -> { throw new UserAccountException("checked"); }).when(repository).findById(id);

3.重新考虑一下您的测试是否正确:

如果无法从模拟方法中抛出该特定异常, 你为什么要测试这个异常?选择更合适的 例外和/或将测试更改为有效的测试用例。

4.在方法中声明
throws
异常,如果是这样的话,它可以抛出此检查异常:

这只有在存储库有自定义的情况下才有意义 实现,或者它是否真的会抛出该异常。

public interface MyRepositoryInterface {
    Optional<My> findById(Long id) throws UserAccountException;
}
© www.soinside.com 2019 - 2024. All rights reserved.