有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在尝试使用mockito抛出已检查异常时出现问题

我有下面的界面

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();

但是编译器告诉我有一个未处理的异常。 检索方法的定义为:

public List<SomeClass> Retrieve() {
    try {
        interface1Object.Execute("");
    }
    catch (Exception exception) {
        return new ArrayList<SomeClass>();
    }
}

mockito文档只显示RuntimeException的用法,我还没有在StackOverflow上看到类似的用法。 我使用的是Java1.7u25和Mockito1.9.5


共 (3) 个答案

  1. # 1 楼答案

    假设您的测试方法没有声明它抛出Exception,那么编译器是绝对正确的。这一行:

    when(interfaceMocked.Execute(anyString())).thenThrow(new Exception());
    

    。。。在Interface1的实例上调用Execute。它可以抛出Exception,因此您需要捕获它或声明您的方法抛出它

    我个人建议只声明测试方法抛出Exception。没有其他东西会关心这个声明,你真的不想抓住它

  2. # 2 楼答案

    您可以使用Mockito的doAnswer方法抛出已检查的异常,如下所示

    Mockito.doAnswer(
              invocation -> {
                throw new Exception("It's not bad, it's good");
              })
          .when(interfaceMocked)
          .Execute(org.mockito.ArgumentMatchers.anyString());
    
  3. # 3 楼答案

    如果您的方法返回某些内容并抛出错误,您不应该遇到问题。现在,如果您的方法返回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方法并确保它返回正确的内容。如果您需要确保您的接口正在抛出异常,那么对于您的接口类来说,这是一个不同的测试

    您必须为一行代码创建一个方法,这可能看起来很糟糕,但如果您想要可测试的代码,有时也会发生这种情况