获取 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);
}
你必须扔一个
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);
}
}
我已经在另一个线程回答了这个问题:
调用
抛出已检查的异常时会抛出此异常 来自未在以下位置声明此已检查异常的方法的异常 抛出。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; }