java - 如何在junit4 Java中测试多行代码是否抛出异常
问题描述
我正在add(T elem, int index)
为一个类的方法写一个否定测试。该方法预计会抛出IllegalArgumentException
if index < 0 || index > size || elem == null
。我的测试如下所示:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test(expected = IllegalArgumentException.class)
public void addNegTest() {
l0.add(42, 10); // index > size
l0.add(42, -1); // index < 0
l0.add(null, 2); // elem == null
}
测试变为绿色,但我发现只需要这 3 行代码中的 1 行即可引发异常,以便测试变为绿色。所以如果我像这样在代码中添加 1 行,测试仍然会变成绿色。
@Test(expected = IllegalArgumentException.class)
public void addNegTest() {
l0.add(42, 10); // index > size
l0.add(42, -1); // index < 0
l0.add(null, 2); // elem == null
l0.add(42, 0); // this is perfectly fine
}
那么我如何确保测试测试是否每一行都抛出异常而不仅仅是一个?
解决方案
预期的异常在整个测试方法执行的范围内是预期的,无论其他一些语句没有抛出它。
所以你应该根据可能的场景创建一个测试方法。
@Test(expected = IllegalArgumentException.class)
public void add_with_index_greater_than_size() {
l0.add(42, 10); // index > size
}
@Test(expected = IllegalArgumentException.class)
public void add_with_index_less_than_zero() {
l0.add(42, -1);
}
@Test(expected = IllegalArgumentException.class)
public void add_with_null_arg() {
l0.add(null, 10);
}
@Test
public void add() {
l0.add(42, 10);
Assert.assertEquals(42, l0.get(10));
}
虽然您仍然可以使用单个测试方法,其中包含与 SilverNak 答案try/catch
中所示的失败场景一样多的语句来测试,但出于可读性原因,我不推荐它。
请注意,除了您的情况之外,在其自己的方法中指定每个不同的场景是一种很好的做法,因为它使测试更具可读性,并且由于其责任更清晰和定义明确,它还使纠正失败的测试变得更简单/更容易。
JUnit 5 改进
请注意,在最新发布的 JUnit 版本中,您可以使用相同的方法收集一些常见案例,而不会降低代码的可读性。
您可以收集传递给错误索引的无效案例,例如:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
...
@Test
public void add_with_index_less_than_zero_or_greater_than_size() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> l0.add(42, 10));
Assertions.assertThrows(IllegalArgumentException.class,
() -> l0.add(42, -1));
}
但我会将这个保留在一个单独的方法中:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
...
@Test
public void add_with_null_arg() {
Assertions.assertThrows(IllegalArgumentException.class,
() -> l0.add(null, 10));
}
推荐阅读
- c# - 如何在 Unity 3D 中使用 goto 属性?
- asp.net-core - VS2019无法使用控制器模板
- reactjs - 如何在 react.js 中使用模板组件?
- asp.net-core - 如何获取适用于 OpenIddict ClientCredential 授权类型的基本身份验证中的客户端密码?
- google-analytics - 用户对此配置文件没有足够的权限谷歌分析
- r - 从 R 闪亮的 sql 中保存数据时出错
- php - php如何使用2个数组创建自定义数组
- amazon-web-services - 启动后如何将 EC2 IP 地址自动添加到 CloudFront WAF
- php - 从 instagram 获取用户个人资料图片
- ubuntu-18.04 - 棘轮 websocket 调用未连接。没有协议处理程序对 URL /wss/ 有效(方案“ws”)。怎么修?