异常处理Java TestNG:为什么我的断言在trycatch块中写入时总是通过
我尝试使用一个简单的代码,使用org.testng.Assert
断言2个用例。在第一个用例中,我断言了两个不相等的值,它们Fail
是正确的
但是在第二个用例中,当我在try-catch块中断言两个不相等的值时,结果总是作为Pass
返回
我的代码如下:
package demo;
import org.testng.Assert;
import org.testng.annotations.Test;
public class Q43710035
{
@Test
public void test1()
{
System.out.println("Within test1");
int a = 12;
int b =20;
Assert.assertEquals(a, b);
}
@Test
public void test2()
{
System.out.println("Within test2");
int a = 12;
int b =20;
try
{
Assert.assertEquals(a, b);
}catch(Throwable t)
{
System.out.println("Exception Occurred");
}
}
}
我得到的结果是:
Within test1
Within test2
Exception Occurred
PASSED: test2
FAILED: test1
java.lang.AssertionError: expected [20] but found [12]
at org.testng.Assert.fail(Assert.java:94)
我的问题是:
- 在test2()中,虽然断言失败了,但为什么执行不是从这个
Test
出来的呢李> - 在test2()中,try块似乎失败了,因此执行到达catch块,并且
Exception Occurred
被打印出来。为什么在执行断言代码时try
块会在这里失败李>
# 1 楼答案
你的第二个案例充满了问题,这就是为什么它表现得如此奇怪。查看由数字标记的行:
1-“assert*”方法调用不应被try-catch块包装。它们被设计用来检查数据,并通过抛出错误(!)来处理数据的无效性
2-你正在尝试捕捉所有可以在try部分抛出的内容。在常见情况下,应用程序的业务逻辑使用异常,而不是错误。异常表明出现了一些问题,您可以从中恢复。错误主要表明出现了一些严重的问题,如(硬盘故障等),您只需在应用程序停止之前处理应用程序的数据。异常和错误是从Throwable继承的。”assert*'方法设计为抛出特定于“catch”块捕获的错误
3-如果你不处理捕获到的异常,你就是在忽略它。这就是为什么你的方法总是成功的
要更正第二次测试,您可以: a) 从方法体中删除try-catch节 b) 将“t”参数的类型从Throwable更改为Exception c) 在“catch”块末尾添加“throw t”
# 2 楼答案
如果您查看
assertEquals
方法的源代码,您将看到它可以归结为fail
方法(就像许多其他断言一样)正如我们所看到的,它抛出
AssertionError
,您正在catch(Throwable t)
中捕获它。因此,JUnit无法判断测试是否失败,从而宣布它通过了测试如果捕获异常是测试的一部分(您预期会发生异常),我建议您查看JUnit文档:Exception testing
# 3 楼答案
后来在理解Java时,我也遇到了类似的问题,即当调用方法想要了解其被调用方法中的异常时,被调用方法应该包含“throw exception;”语句在其Catch块中
这样,
TestNG会知道,抛出了一个异常。然后,TestNG将使该方法失败
请注意,例如printStackTrace();也不会让你的测试失败
# 4 楼答案
如果您浏览junit4的源代码,https://github.com/junit-team/junit4/blob/master/src/main/java/junit/framework/Assert.java#L71
您将了解test1失败的原因
第1部分:
第2部分:
第三部分:
因此,您已收到第3部分的返回消息
要全面了解异常JUnit规则,请通过following tutorial:
预期异常JUnit规则
要断言JUnit引发了异常,通常使用try/fail/catch习惯用法或@Test注释的预期元素。尽管比前者更简洁,但有一种观点认为使用expected并不支持您可能要测试的所有情况。示例是在异常后执行附加测试或针对实际异常消息进行测试
JUnit4.7引入了next progression,这是一条@规则,它提供了两个世界中最好的东西。本文权衡了每种方法的优缺点,并仔细研究了每种方法的语法。 try/fail/catch成语
典型的模式是捕获异常,如果从未抛出,则显式失败
这将以以下方式突出显示故障
该习惯用法的潜在优势在于,它提供了针对实际异常进行断言的机会,以及在预期之后执行额外工作的机会。除了噪音之外,主要的缺点是很容易忘记包含失败调用。如果真的先做测试,我们总是以红色运行测试,这不会是一个问题,但很多时候事情都会漏网之鱼。在实践中,我已经看到了太多的例子,其中一个遗漏的失败给出了误报
@测试(预期=异常.class)
使用预期的元素,我们可以如下重写测试
这将导致以下故障
资源链接:What exactly does assertEquals check for when asserting lists?