带有异常期望的 JUnit 测试(多个断言)

发布于 2024-12-22 12:35:05 字数 1090 浏览 4 评论 0原文

我正在测试 WeekConverter 以供 Xalan 使用,并想知道我的测试到底在做什么。 :D

具有以下测试方法:

@Test(expected = IllegalArgumentException.class)
  public void testConvertTwoDigitYearWithWrongInput() {
  WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR);

  //wrong or empty inputs
  assertEquals("0", weekConverter.convert(""));
  assertEquals("0", weekConverter.convert("abcdefgh"));
}

此测试是否会期望所有断言出现异常,还是仅第一个断言出现异常?如果只是第一个,这意味着我必须为每个断言创建一个测试方法,尽管我期望在这两种情况下出现相同的异常。有人可以在这里确认我的例子吗?

我还对 null 进行了测试,这会产生 NullPointerException。软验证如下:

if (inputDate == null) {
  do something and throw NullPointerexception
} else if (inputDate.isEmpty()) {
  do something and throw IllegalArgumentException, since inputDate is not really null
} else if (inputDate.matches(regex)) {
  go futher and convert
} else {
  do something and throw IllegalArgumentException, since inputDate does not match regex
}

因此,一个测试方法期望带有两个断言的 IllegalArgumentException。但很明显,我需要两种不同的测试方法,不仅要尊重 JUnit 的功能,而且我期望从两种不同的状态抛出异常。

I'm testing a WeekConverter for Xalan use and wondering what is my test exactly doing. :D

Having the following test method:

@Test(expected = IllegalArgumentException.class)
  public void testConvertTwoDigitYearWithWrongInput() {
  WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR);

  //wrong or empty inputs
  assertEquals("0", weekConverter.convert(""));
  assertEquals("0", weekConverter.convert("abcdefgh"));
}

Will this test expect an exception for all asserts, or only for the first assert? If only the first, which would mean that I have to create a test method for each assert, although I'm expecting the same exception in both cases. Can someone confirm my example here, please?

I also have a test for null, which yields a NullPointerException. The soft validation is the following:

if (inputDate == null) {
  do something and throw NullPointerexception
} else if (inputDate.isEmpty()) {
  do something and throw IllegalArgumentException, since inputDate is not really null
} else if (inputDate.matches(regex)) {
  go futher and convert
} else {
  do something and throw IllegalArgumentException, since inputDate does not match regex
}

Therefore the one test method expecting IllegalArgumentException with two asserts. But it's obvious that I need two different test methods, not only to respect functionality of JUnit , but also that I expect a throw from two different states.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

和我恋爱吧 2024-12-29 12:35:05

您可以将方法分解为多个方法,但如果您有很多输入样本,那就会很不方便。

您可以改用以下方法:

@Test
public void testConvertTwoDigitYearWithWrongInput() {
    WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR); 

    assertFailsToConvert(weekConverter, ""); 
    assertFailsToConvert(weekConverter, "abcdefgh");
}

private void assertFailsToConvert(WeekConverter weekConverter, String input) {
    try {
        weekConverter.convert(input);
        fail("Should not convert [" + input + "]");
    } catch (IllegalArgumentException ex) {}
}

You can break your method into multiple methods, but if you have many input samples it would be inconvenient.

You can use the following approach instead:

@Test
public void testConvertTwoDigitYearWithWrongInput() {
    WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR); 

    assertFailsToConvert(weekConverter, ""); 
    assertFailsToConvert(weekConverter, "abcdefgh");
}

private void assertFailsToConvert(WeekConverter weekConverter, String input) {
    try {
        weekConverter.convert(input);
        fail("Should not convert [" + input + "]");
    } catch (IllegalArgumentException ex) {}
}
手心的温暖 2024-12-29 12:35:05

您应该提供多种测试方法,因为它们正在测试不同的东西。

转换器第一次获得非法参数时将抛出异常。

您还应该测试空输入,只是为了记录行为。

You should provide multiple test methods, since they're testing different things.

The exception will be thrown the first time the converter gets an illegal argument.

You should also test a null input, just to document behavior.

涙—继续流 2024-12-29 12:35:05

测试只是期望抛出 IllegalArgumentException,无论从何处或为何抛出它。

我建议您将其分为两个测试。

The test is just expecting that IllegalArgumentException is being throw, regardless from where or why it is being throwed.

I recommend you to split it in two tests.

北恋 2024-12-29 12:35:05

您可以将转换装置的创建放在单独的 @Before 设置方法中,然后您可以拥有(三个)单独的测试用例来处理 null、“”和“abcdef”。

如果还有更多的案例需要测试,
JUnit 中一个巧妙的方法是使用 @Parameters 注释和相应的跑步者。

您的测试类将仅处理不正确的两位数年份。它的构造函数将使用 String 类型的 inputDate 进行参数化。

生成 @Parameters 的静态方法将返回一个包含 ""abcdefg (以及其他有趣的情况)的集合。

单个测试用例需要一个 IllegalArgumentException

@RunWith(Parameterized.class)
public class IncorrectTwoDigitYears {
    String inputDate;

    public IncorrectTwoDigitYears(String inputDate) {
        this.inputDate = inputDate;
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFormat() {
        (new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR))
            .convert(inputDate);
    }

    @Parameters
    public static Collection<Object[]> data() {
       Object[][] data = new Object[][] { 
           { "" }, { "abcdef" }, { "0" }, { "000" }, { "##" } };
       return Arrays.asList(data);
    }
}

如果您有不止两个案例需要测试,回报会更高。

You can put the creation of the conversion fixture in a separate @Before setup method, and then you can have (three) separate test cases for dealing with null, "", and "abcdef".

If there are more cases to test,
a neat way in JUnit is to use the @Parameters annotation and corresponding runner.

Your test class would deal with incorrect two digit years only. Its constructor would be parameterized with an inputDate of type String.

The static method yielding the @Parameters would return a collection containing "" and abcdefg (and other funny cases).

The single test case would expect an IllegalArgumentException.

@RunWith(Parameterized.class)
public class IncorrectTwoDigitYears {
    String inputDate;

    public IncorrectTwoDigitYears(String inputDate) {
        this.inputDate = inputDate;
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFormat() {
        (new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR))
            .convert(inputDate);
    }

    @Parameters
    public static Collection<Object[]> data() {
       Object[][] data = new Object[][] { 
           { "" }, { "abcdef" }, { "0" }, { "000" }, { "##" } };
       return Arrays.asList(data);
    }
}

The pay off will be higher if you have more than just two cases to test.

避讳 2024-12-29 12:35:05

尝试catch-Exception

@Test
public void testConvertTwoDigitYearWithWrongInput() {

    WeekConverter weekConverter = ...

    // wrong or empty inputs
    verifyException(weekConverter, IllegalArgumentException.class)
       .convert("");
    verifyException(weekConverter, IllegalArgumentException.class)
       .convert("abcdefgh");
}

Try catch-exception:

@Test
public void testConvertTwoDigitYearWithWrongInput() {

    WeekConverter weekConverter = ...

    // wrong or empty inputs
    verifyException(weekConverter, IllegalArgumentException.class)
       .convert("");
    verifyException(weekConverter, IllegalArgumentException.class)
       .convert("abcdefgh");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文