检查junit中是否为所有语句抛出异常的最有效方法是什么?

时间:2014-09-29 18:48:07

标签: java exception junit

我有一个函数在给出无效输入时抛出ParseException,我想为它编写一个单元测试。此测试旨在确保在所有无效输入上引发异常。 (对于这个问题,假设输入以[开头,以]结尾,没有[或{{ 1}}在其他任何地方。)

我目前有这个测试:

]

它有效,但它看起来不是正确的方式。我尝试使用ExpectedException,但代码仍然会立即退出。 (我试过的是这个:

@Test
public void invalidListFromatShouldFail() {        
    final String[] tests = {
            "[[]",
            "[]]",
            "[] hi",
            "hi",
            "[h]i",
            "[hi []",
            "[[]]"
    };

    for(String toTest : tests) {
        try {
            ListUtil.parseList(toTest, TestEnum.class);
        } catch (ParseException e) {
            assertThat(e.getMessage(), startsWith(
                    "§cList format is invalid: It must start with " +
                    "'[' and end with ']', and not have any '['" + 
                    " or ']' anywhere else in it."));
            continue;
        }
        fail("Exception was not thrown for " + toTest + "!");
    }
}

但只测试第一个值;如果我在最后放置@Test public void invalidListFromatShouldFail() throws ParseException { expected.expect(ParseException.class); expected.expectMessage(startsWith( "§cList format is invalid: It must start with " + "'[' and end with ']', and not have any '['" + " or ']' anywhere else in it.")); ListUtil.parseList("[[]", TestEnum.class); ListUtil.parseList("[]]", TestEnum.class); //ECT... } 它仍然会成功,因为发生了异常)。

我的问题是:是否有更优雅的方式来编写此测试,使用ExpectedException或其他方法?

3 个答案:

答案 0 :(得分:2)

使用JUnit参数化测试:https://github.com/junit-team/junit/wiki/Parameterized-tests

作为替代方案,您可以使用JUnitParams:https://github.com/Pragmatists/junitparams

干杯,

答案 1 :(得分:1)

实际上,你似乎需要两件事。一个是编写一个测试,检查是否抛出异常而另一个是针对多个输入运行相同的测试。

首先,从参数化测试开始。在这种方法中,编写测试方法,使其仅针对单个输入运行,并且附加代码(通常是注释)使此方法针对多个输入运行。这使您的代码更简单,因为您不必编写循环或将数据放入某个数组或列表中。您可以使用JUnit的内置Parameterized测试运行器(docs and example),但我个人觉得它的语法很麻烦。我的建议是使用JUnitParams,它具有非常简洁和甜美的语法。

要检查在测试单个输入的方法中是否抛出异常,可以使用expected注释中的@Test参数。另一种方法是使用catch-exception library,如果你有更长的测试,那就更好了。在这里,我认为内置功能足够好。

因此,使用JUnitParams和expected注释参数,您的测试可能如下所示:

@Test(expected = ParseException.class)
@Parameters(
    "[[]",
    "[]]",
    "[] hi",
    "hi",
    "[h]i",
    "[hi []",
    "[[]]"
)
public void invalidListFromatShouldFail(String input) {        
    ListUtil.parseList(toTest, TestEnum.class);
}

这也很简短,也是可读的。

编辑: Here是使用Parameterized的更好示例,它还提到@Parameter注释,它允许您将值直接注入字段而不使用需要在测试类中创建构造函数。尽管如此,我还是推荐使用JUnit Params而不是Parameterized因为易用性和测试可读性方面的差异很大。

答案 2 :(得分:-1)

您需要使用以下内容注释您的测试:

@Test(expected = YourException.class)

这是一个很好的教程:http://www.mkyong.com/unittest/junit-4-tutorial-2-expected-exception-test/

还可以查看参数化测试:https://github.com/junit-team/junit/wiki/Parameterized-tests