JUnit testing with exception expectations (multiple asserts)
我正在测试一个用于Xalan的WeekConverter,并想知道我的测试究竟做了什么。:d
有以下测试方法:
1 2 3 4 5 6 7 8 | @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。 软验证如下:
1 2 3 4 5 6 7 8 9 | 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的功能,还要考虑两种不同状态的抛出。
您可以将方法分解为多种方法,但如果您有许多输入样本,则会很不方便。
您可以使用以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @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) {} } |
尝试catch异常:
1 2 3 4 5 6 7 8 9 10 11 | @Test public void testConvertTwoDigitYearWithWrongInput() { WeekConverter weekConverter = ... // wrong or empty inputs verifyException(weekConverter, IllegalArgumentException.class) .convert(""); verifyException(weekConverter, IllegalArgumentException.class) .convert("abcdefgh"); } |
您可以将转换夹具的创建放在单独的@Before安装方法中,然后您可以有(三个)单独的测试用例来处理null,"和"abcdef"。
如果有更多案例需要测试,
JUnit中一个简洁的方法是使用@Parameters注释和相应的运行器。
您的测试类仅处理不正确的两位数年份。它的构造函数将使用String类型的
产生
单个测试用例期望
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @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); } } |
如果您只有两个案例需要测试,那么回报会更高。
测试只是期望IllegalArgumentException被抛出,无论从何处或为何被抛出。
我建议你分两次测试。
你应该提供多种测试方法,因为他们正在测试不同的东西。
转换器第一次获得非法参数时将抛出异常。
您还应测试空输入,仅用于记录行为。