Java - TestNG:为什么我的Assertion总是在try-catch块中写入时通过

Deb*_*anB 8 java testng exception-handling try-catch assertions

我正在尝试使用一个简单的代码org.testng.Assert来断言2个用例.在第一个用例中,我Fail正确地声明了2个不相等的值.

但是在第二个用例中,当我在try-catch块中断言2个不相等的值时,结果总是返回为 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

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)
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 在test2()中尽管断言失败了,为什么执行不会出现Test
  2. 在test2()中,似乎try块失败,因此执行到达catch块Exception Occurred并被打印.try当断言代码执行时,为什么块会在这里失败?

Car*_*geh 11

如果你看一下assertEquals方法的源代码,你会发现它都归结为fail方法(和许多其他断言一样).

public static void fail(String message) {
    if(message == null) {
        throw new AssertionError();
    } else {
        throw new AssertionError(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,它会抛出AssertionError,你正在捕捉它catch(Throwable t).所以JUnit无法告诉测试失败,因此声明它已通过.

如果捕获异常是测试的一部分(您期望异常),我建议您查看JUnit文档:异常测试


Sky*_*ker 3

如果你浏览junit4的源代码, https://github.com/junit-team/junit4/blob/master/src/main/java/junit/framework/Assert.java#L71

\n\n

你会明白 test1 失败的原因

\n\n

第1部分:

\n\n
\n
/**\n * Asserts that two objects are equal. If they are not\n * an AssertionFailedError is thrown with the given message.\n */\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n
static public void assertEquals(String message, Object expected, Object actual) {\n    if (expected == null && actual == null) {\n        return;\n    }\n    if (expected != null && expected.equals(actual)) {\n        return;\n    }\n    failNotEquals(message, expected, actual); //It calls Part#2\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

第2部分:

\n\n
static public void failNotEquals(String message, Object expected, Object actual) {\n    fail(format(message, expected, actual)); //It calls Part#3 format(...) method\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

第 3 部分:

\n\n
public static String format(String message, Object expected, Object actual) {\n    String formatted = "";\n    if (message != null && message.length() > 0) {\n        formatted = message + " ";\n    }\n    return formatted + "expected:<" + expected + "> but was:<" + actual + ">";\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以你已经收到了 Part#3 的返回消息

\n\n
\n

java.lang.AssertionError:预期 [20] 但发现 [12]

\n
\n\n

要完整了解异常 JUnit 规则,请阅读以下教程

\n\n

预期异常 JUnit 规则

\n\n

要断言 JUnit 引发了异常,通常使用 try/fail/catch 习惯用法或 @Test 注释的预期元素。尽管比前者更简洁,但有一个论点是使用预期并不支持您可能想要测试的所有情况。该示例是在异常发生后执行附加测试或针对实际异常消息进行测试。

\n\n

JUnit 4.7 引入了下一个进展,即提供两全其美的 @Rule。本文权衡了每种方法的优缺点,并仔细研究了每种方法的语法。\ntry/fail/catch 习惯用法

\n\n

典型的模式是捕获异常,或者如果从未抛出异常则显式失败。

\n\n
@Test\npublic void example1() {\n    try {\n        find("something");\n        fail();\n    } catch (NotFoundException e) {\n        assertThat(e.getMessage(), containsString("could not find something"));\n    }\n    // ... could have more assertions here\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将通过以下方式突出显示失败。

\n\n
java.lang.AssertionError: expected an exception\n    at org.junit.Assert.fail(Assert.java:91)\n    at bad.roboot.example.ExceptionTest.example1(ExceptionTest.java:20)\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

该习惯用法具有潜在的优势,因为它提供了针对实际异常进行断言以及在预期之后执行额外工作的机会。除了噪音之外,主要缺点是很容易忘记包含失败调用。如果真正先进行测试,我们总是运行红色测试,这不会成为问题,但事情常常会漏网。在实践中,我\xe2\x80\x99见过太多缺少失败而导致误报的例子。

\n\n

@Test(预期= Exception.class)

\n\n

使用预期的元素,我们可以按如下方式重写测试。

\n\n
@Test (expected = NotFoundException.class)\npublic void example2() throws NotFoundException {\n    find("something");\n    // ... this line will never be reached when the test is passing\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将导致以下失败。

\n\n
java.lang.AssertionError: Expected exception: bad.robot.example.NotFoundException\n
Run Code Online (Sandbox Code Playgroud)\n\n

资源链接: 断言列表时,assertEquals 到底检查什么?

\n