我有以下界面
public interface Interface1 {
Object Execute(String commandToExecute) throws Exception;
}
然后我试图模拟,所以我可以测试将调用它的类的行为:
Interface1 interfaceMocked = mock(Interface1.class);
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
Interface2 objectToTest = new ClassOfInterface2(interfaceMocked);
retrievePrintersMetaData.Retrieve();
但是编译器告诉我有一个未处理的异常。 Retrieve方法的定义是:
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return new ArrayList<SomeClass>();
}
}
mockito文档仅显示RuntimeException的使用,我在StackOverflow上没有看到类似的东西。 我正在使用Java 1.7u25和mockito 1.9.5
答案 0 :(得分:3)
假设您的测试方法没有声明它抛出Exception
,编译器绝对正确。这一行:
when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
...在Execute
的实例上调用Interface1
。这可以抛出Exception
,因此您需要捕获它或声明您的方法抛出它。
我个人建议只声明测试方法会抛出Exception
。没有其他人会关心这个宣言,你真的不想抓住它。
答案 1 :(得分:0)
如果您的方法返回某些内容并引发错误,则不应该遇到问题。现在,如果您的方法返回void,您将无法抛出错误。
现在真的是你没有测试你的接口抛出异常,而是你在测试在这个方法中抛出异常时会发生什么。
public List<SomeClass> Retrieve() {
try {
interface1Object.Execute("");
}
catch (Exception exception) {
return handleException(exception);
}
}
protected List<SomeClass> handleException(Exception exception) {
return new ArrayList<SomeClass>();
}
然后你只需调用handleException方法并确保它返回正确的东西。如果您需要确保您的接口抛出异常,那么这是对您的接口类的不同测试。
你必须为单行创建一个方法似乎很麻烦但是如果你想要可测试的代码,有时会发生这种情况。
答案 2 :(得分:0)
您可以使用Mockito的doAnswer方法引发已检查的异常,像这样
Mockito.doAnswer(
invocation -> {
throw new Exception("It's not bad, it's good");
})
.when(interfaceMocked)
.Execute(org.mockito.ArgumentMatchers.anyString());