尝试使用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();

但是编译器告诉我有一个未处理的异常。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

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

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

在CCD_ 3的实例上调用CCD_。这可能会抛出Exception,所以您要么需要捕获它,要么声明您的方法抛出了它

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

您可以使用Mockito的doAnswer方法来抛出已检查的异常,比如这个

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

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

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

相关内容

  • 没有找到相关文章

最新更新