问题描述
示例代码:
public Interface FlightBehavIoUr {
void fly();
}
public class Fly implements FlightBehavIoUr {
@Override
public void fly() throws CrashWithObject {
// does something to fly
}
}
public class CanNotFly implements FlightBehavIoUr {
@Override
public void fly() {
// does not fly
}
}
public class Bird() {
private FlightBehavIoUr fly;
public void setFlightBehavIoUr(FlightBehavIoUr flightBehavIoUr) {
this.car = car;
}
@Override
public void fly() throws CrashWithObject {
car.fly();
}
}
JUnit:
@Test
public void testFlighBehavIoUrOfNonFlyingBird() {
// ...
Bird plasticDuck = new Bird();
plasticDuck.setFlightBehavIoUr(new CanNotFly());
plasticDuck.fly(); //Compiler shows that an Exception is thrown
// However,I kNow that this will never happen since my Bird can't fly
// and therefore never throws an exception
// ...
}
这是我的实现的简单复制。如您所见,我正在使用策略模式。
我的问题是:如何抑制给出的警告?
解决方法
在测试用例中,你不应该假设不能抛出异常,而是测试它(通过在异常的情况下使测试失败,也许是在试图引发它)。
使用您的(基于策略模式的)代码结构,编译器几乎不可能推断不会抛出异常。作为人类,我们已经面临着这种推理的艰巨工作(忽略代码中的一些错别字):
-
Bird.fly()
方法仅在CrashWithObject
抛出时才会抛出fly.fly()
。 -
fly
最近被设置为CannotFly
中的plasticDuck.setFlightBehaviour(new CanNotFly());
。 -
CannotFly.fly()
不会抛出CrashWithObject
。 - 可能没有为此
setFlightBehaviour()
实例在其他任何地方调用Bird
,但这需要对整个应用程序进行彻底分析才能真正确定这一点。 - 因此,我们希望
fly
字段在CannotFly
调用时仍保持plasticDuck.fly()
的实例,这使我们可以得出结论,没有CrashWithObject
可以是抛出。
你看,它需要对各种代码片段进行大量非平凡的推理才能得出无例外的结论,这是我不希望很快在编译器中看到的深度推理。