2

我有一个Game带有以下签名的构造函数的类:

public Game(String[] boardState) throws InvalidStringsInputException, WrongNumberOfMarksException

在junit4测试用例中有一个方法:

public static Game newGameFromStringsSuccessful(String[] input) //it is the line 9
{
    try
    {
        return new Game(input);
    }
    catch (WrongNumberOfMarksException exception)
    {
        fail("Caught exception where it shouldn't be");
    }
    catch (InvalidStringsInputException exception)
    {
        fail("Caught exception where it shouldn't be");
    }
}

我正在使用 Eclipse,它向我显示了一个错误: This method must return a result of type Game line 9 Java Problem

如果我return null在两个块的末尾插入catch,错误就会消失,但我的问题没有:为什么即使在调用 fail() 方法之后 java 也想要它?

4

2 回答 2

3

为什么即使在调用 fail() 方法之后 java 也想要它?

因为编译器不知道不能fail正常返回。在 Java 中无法表达这一点。消息调用的结束fail仍然是可达的——所以方法的结束也是可达的。

假设方法中有一个错误fail,所以你最终到达了方法的末尾——你期望会发生什么?

最简单的解决方法是在方法结束时抛出一些运行时异常,例如AssertionError

throw new AssertionError("fail must have returned normally!");

说“世界很疯狂,我不想再住在这里”基本上是一个例外——这也让编译器感到高兴,因为方法的右括号不再可访问。

另一种选择 - 这里不可用,因为您不控制该fail方法 - 将声明该fail方法以返回某种运行时异常,此时您的 catch 块可能如下所示:

catch (InvalidStringsInputException exception)
{
    throw fail("Caught exception where it shouldn't be");
}

当然,实现仍然是fail抛出异常而不是返回它,但这意味着编译器知道那个 catch 块肯定不会正常完成。

于 2013-07-01T16:01:08.913 回答
1

Jon 在下面的回答解释了编译器抱怨的原因。但是,我建议避免这种情况的正确方法是不要进行try/catch测试。只需让异常传播到调用堆栈并退出您的测试。JUnit 将捕获它并使测试失败,同时提供引发异常的整个堆栈跟踪。

或者,如果您不想传播该throws子句,请将异常包装在 a 中RuntimeException,然后将其抛出。同样,这将提供堆栈跟踪以进行更好的诊断。

于 2013-07-01T17:23:01.190 回答