有 Java 编程相关的问题?

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

java TDD与不可能的例外

我对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块。 所以我想要这样的课程:

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块编写测试——因此我无法在Bar内部编写try/catch块,因为TDD说“只有在灯是红色时才写代码”

这是一个末日循环

我希望你抓住了我! 谢谢


共 (3) 个答案

  1. # 1 楼答案

    您可以将Fuffes声明添加到测试方法中,如FGE已经建议的,或者您可以考虑通过将IF分割成两个单独的方法(一个抛出异常,另一个不使用)来重新设计代码。

    class Foo {
    
        public String getStringWithException() throws Exception {
            // return data or throw exception if something goes wrong
        }
    
        public String getStringWithoutException() {
            // return data
        }
    

    }

  2. # 2 楼答案

    使测试本身抛出异常:

    public void testShouldReturnReversedStringOfBar() 
        throws Exception
    {
        Bar bar = new Bar();
    
        assertEquals("esnesnon", bar.getReversedString());
    }
    

    如果抛出异常,那么测试将被标记为错误;这是“一次失败,但不是我们所知道的,吉姆”,但还是失败了


    顺便说一句,扔Exception是一种不好的习惯;当您捕获Exception时,您还可以捕获所有RuntimeException,也就是说,所有未检查的异常。不要那样做

  3. # 3 楼答案

    TDD是一种帮助您验证程序能否正常工作的方法。尽管Exception永远不会发生。我想你可以用{}测试方法。就像:

    public void testShouldReturnReversedStringOfBar() throw Exception{
        ....
    }