我遇到了TDD问题和不可能的例外情况。
假设我们有一个名为Foo的类(示例):
Class Foo {
public String getString(boolean shouldThrow) throws Exception {
if(shouldThrow) throw new Exception();
return "nonsense";
}
}
Foo仅在某些情况下抛出异常(为简单起见,我在这里采用布尔值)。
现在我想创建一个名为Bar的类,它可以反转Foo的字符串而不会抛出异常。
测试:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
assertEquals("esnesnon", bar.getReversedString());
}
}
我知道布尔值一直都是假的。所以方法getReversedString()永远不会抛出异常。但是因为它不会抛出任何异常,所以我不能写一个断言,它导致我在Bar中编写try / catch块。
所以测试看起来像这样:
class BarTest {
public void testShouldReturnReversedStringOfBar() {
Bar bar = new Bar();
try {
assertEquals("esnesnon", bar.getReversedString());
} catch (Exception e) {
// ... will never happen
}
}
}
但这很糟糕,因为异常永远不会发生,我每次使用getReversedString()方法时都必须编写try / catch-block。 所以我想要这样的课程:
class Bar {
public String getReversedString() {
Foo foo = new Foo();
try {
String s = foo.getString(false);
} catch (Exception e) {
// will never happen...
}
// ... reverse string ...
return reversedString;
}
}
但是由于异常永远不会发生,我不能为try / catch-block编写测试 - 因此我无法在Bar内部编写try / catch-block,因为TDD说“只编写代码,如果灯是红色的。“
这是一个厄运循环...
我希望你能帮帮我! 谢谢!
答案 0 :(得分:4)
让测试本身抛出异常:
public void testShouldReturnReversedStringOfBar()
throws Exception
{
Bar bar = new Bar();
assertEquals("esnesnon", bar.getReversedString());
}
如果抛出异常,则测试将被标记为错误;吉姆"这是一个失败,但不是我们所知道的。 - 无论如何都失败了。
顺便说一句,抛出Exception
是不好的做法;当你抓住Exception
时,你也可以捕获所有RuntimeException
,也就是所有未经检查的异常。别这么做。
答案 1 :(得分:0)
你可以像fge已经建议的那样在测试方法中添加一个throws声明,或者你可以考虑通过将if分成两个单独的方法(一个抛出异常,一个抛出异常)来重新设计你的代码。
class Foo {
public String getStringWithException() throws Exception {
// return data or throw exception if something goes wrong
}
public String getStringWithoutException() {
// return data
}
}
答案 2 :(得分:0)
TDD
是一种帮助您验证程序是否可以正常运行的方法。虽然Exception
永远不会发生。我认为您可以在throw Exception
测试方法中junit
。就像:
public void testShouldReturnReversedStringOfBar() throw Exception{
....
}