JUnit 4:多次期待一个异常
JUnit 4 : Expect one exception multiple times
我有如下一段代码:
@Test(expected = IllegalArgumentException.class)
public void failureTest() {
testedObject.supposedToFail("");
testedObject.supposedToFail(null);
}
当 运行 执行此操作时,我无法保证会抛出带有 null
参数的 IllegalArgumentException
。实际上,只要 JUnit 遇到第一个异常,它就会停止整个方法的 运行。
考虑到我必须为此尝试的测试用例的数量 class (~20),我怀疑编写 20 个方法,每个方法都期望一个特定的异常(通常是相同的)是否有效。
有没有什么方法可以让每个方法同时抛出一个特定的异常? (例如,对于我的示例,您将使用这两种方法)
谢谢
我会使用辅助方法,这样做:
编辑:这不起作用,请参阅替代工作解决方案
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void myTest() {
List<Object[]> paramsList = Arrays.asList(
new Object[] {"", IllegalArgumentException.class},
new Object[] {null, NullPointerException.class});
paramsList.forEach(a -> assertExceptionForParam((String)a[0], (Class)a[1]));
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
thrown.expect(expectedExceptionClass);
testedObject.supposedToFail(param);
}
替代工作解决方案,在 MIRZAK
评论后更改
我的解决方案似乎实际上只测试列表中的第一个案例。这是一个可以测试它们的工作版本
@Test
public void myTest() {
List<Object[]> paramsList = Arrays.asList(
new Object[] {null, NullPointerException.class},
new Object[] {"", IllegalArgumentException.class},
new Object[] {"zip", NullPointerException.class});
paramsList.forEach(a -> assertExceptionForParam((String)a[0], (Class)a[1]));
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
boolean pass = false;
try {
testedObject.supposedToFail(param);
} catch(Exception e) {
pass = e.getClass() == expectedExceptionClass;
}
Assert.assertTrue("test failed for param:" + param + " and Exception "+expectedExceptionClass, pass);
}
如预期的那样输出:
java.lang.AssertionError: test failed for param:zip and Exception class java.lang.NullPointerException
注意,这不是 junit 的解决方案,但让我分享一下如何在 spock
上实施相同的测试:
def "supposedToFail(String) throws IllegalArgumentException when the given argument is null or blank"() {
when:
testedObject.supposedToFail(givenArgument)
then:
thrown(IllegalArgumentException)
where:
givenArgument << [null, '', ' ', '\n']
}
Spock
可以与 junit 一起用于您的 Java 项目,没有任何问题。
不幸的是,辅助方法在那种情况下不起作用,因为即使只有一个辅助方法调用抛出异常,@Test 方法也会通过。
我没有找到一个漂亮的方法来实现这样的测试,结果是这样的:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testThrowIllegalArgumentExceptionForEmptyParam() {
assertExceptionForParam("", IllegalArgumentException.class);
}
@Test
public void testThrowNullPointerExceptionForNullParam() {
assertExceptionForParam(null, NullPointerException.class);
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
thrown.expect(expectedExceptionClass);
testedObject.supposedToFail(param);
}
如果测试失败,您将清楚地了解失败的时间和地点,并且您的代码不会包含大量样板文件。
我有如下一段代码:
@Test(expected = IllegalArgumentException.class)
public void failureTest() {
testedObject.supposedToFail("");
testedObject.supposedToFail(null);
}
当 运行 执行此操作时,我无法保证会抛出带有 null
参数的 IllegalArgumentException
。实际上,只要 JUnit 遇到第一个异常,它就会停止整个方法的 运行。
考虑到我必须为此尝试的测试用例的数量 class (~20),我怀疑编写 20 个方法,每个方法都期望一个特定的异常(通常是相同的)是否有效。
有没有什么方法可以让每个方法同时抛出一个特定的异常? (例如,对于我的示例,您将使用这两种方法)
谢谢
我会使用辅助方法,这样做:
编辑:这不起作用,请参阅替代工作解决方案
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void myTest() {
List<Object[]> paramsList = Arrays.asList(
new Object[] {"", IllegalArgumentException.class},
new Object[] {null, NullPointerException.class});
paramsList.forEach(a -> assertExceptionForParam((String)a[0], (Class)a[1]));
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
thrown.expect(expectedExceptionClass);
testedObject.supposedToFail(param);
}
替代工作解决方案,在 MIRZAK
评论后更改我的解决方案似乎实际上只测试列表中的第一个案例。这是一个可以测试它们的工作版本
@Test
public void myTest() {
List<Object[]> paramsList = Arrays.asList(
new Object[] {null, NullPointerException.class},
new Object[] {"", IllegalArgumentException.class},
new Object[] {"zip", NullPointerException.class});
paramsList.forEach(a -> assertExceptionForParam((String)a[0], (Class)a[1]));
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
boolean pass = false;
try {
testedObject.supposedToFail(param);
} catch(Exception e) {
pass = e.getClass() == expectedExceptionClass;
}
Assert.assertTrue("test failed for param:" + param + " and Exception "+expectedExceptionClass, pass);
}
如预期的那样输出:
java.lang.AssertionError: test failed for param:zip and Exception class java.lang.NullPointerException
注意,这不是 junit 的解决方案,但让我分享一下如何在 spock
上实施相同的测试:
def "supposedToFail(String) throws IllegalArgumentException when the given argument is null or blank"() {
when:
testedObject.supposedToFail(givenArgument)
then:
thrown(IllegalArgumentException)
where:
givenArgument << [null, '', ' ', '\n']
}
Spock
可以与 junit 一起用于您的 Java 项目,没有任何问题。
不幸的是,辅助方法在那种情况下不起作用,因为即使只有一个辅助方法调用抛出异常,@Test 方法也会通过。
我没有找到一个漂亮的方法来实现这样的测试,结果是这样的:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testThrowIllegalArgumentExceptionForEmptyParam() {
assertExceptionForParam("", IllegalArgumentException.class);
}
@Test
public void testThrowNullPointerExceptionForNullParam() {
assertExceptionForParam(null, NullPointerException.class);
}
private void assertExceptionForParam(String param, Class expectedExceptionClass) {
thrown.expect(expectedExceptionClass);
testedObject.supposedToFail(param);
}
如果测试失败,您将清楚地了解失败的时间和地点,并且您的代码不会包含大量样板文件。