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

时间:2017-05-01 12:08:43

标签: java exception-handling try-catch testng 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");
        }
    }
}

我得到的结果是:

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)

我的问题是:

  1. 在test2()中,尽管断言失败了,为什么执行不是来自Test
  2. 在test2()中,似乎try块失败,因此执行到达catch块并打印Exception Occurred。当断言代码执行时,为什么try阻塞失败?

3 个答案:

答案 0 :(得分:11)

如果您查看assertEquals方法的源代码,您会发现这一切都归结为fail方法(与许多其他断言一样)。

public static void fail(String message) {
    if(message == null) {
        throw new AssertionError();
    } else {
        throw new AssertionError(message);
    }
}

正如我们所看到的那样,它会引发AssertionError catch(Throwable t)。所以 JUnit无法告知测试失败,因此声明它已通过。

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

答案 1 :(得分:3)

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

您将了解test1失败的原因

部分#1:

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

部分#2:

static public void failNotEquals(String message, Object expected, Object actual) {
    fail(format(message, expected, actual)); //It calls Part#3 format(...) method
}

部分#3:

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

所以你已经把第3部分的回复信息作为

  

java.lang.AssertionError:expected [20]但找到[12]

要完全了解异常JUnit规则,请浏览following tutorial

期待例外JUnit规则

为了断言使用JUnit抛出异常,使用try / fail / catch惯用法或@Test批注的期望元素是相当常见的。尽管比前者更简洁,但有一种观点认为使用预期并不支持您可能想要测试的所有情况。示例是在异常之后执行附加测试或针对实际异常消息进行测试。

JUnit 4.7引入了下一个进程,一个提供两全其美的@Rule。本文重点介绍了每种方法的优缺点,并仔细研究了每种方法的语法。 try / fail / catch Idiom

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

@Test
public void example1() {
    try {
        find("something");
        fail();
    } catch (NotFoundException e) {
        assertThat(e.getMessage(), containsString("could not find something"));
    }
    // ... could have more assertions here
}

会以下列方式强调失败。

java.lang.AssertionError: expected an exception
    at org.junit.Assert.fail(Assert.java:91)
    at bad.roboot.example.ExceptionTest.example1(ExceptionTest.java:20)
    ...

这个成语具有潜在的优势,因为它提供了对实际例外进行断言以及在期望之后执行额外工作的机会。除了噪音之外,主要的缺点是它很容易忘记包括失败呼叫。如果真的首先进行测试,我们总是在测试中运行红色,这不会是一个问题,但是经常会出现问题。在实践中,我已经看到太多的例子,遗漏失败给出误报。

@Test(expected = Exception.class)

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

@Test (expected = NotFoundException.class)
public void example2() throws NotFoundException {
    find("something");
    // ... this line will never be reached when the test is passing
}

会导致以下失败。

java.lang.AssertionError: Expected exception: bad.robot.example.NotFoundException

资源链接: What exactly does assertEquals check for when asserting lists?

答案 2 :(得分:1)

我也遇到过类似的问题,后来在理解Java的时候,当调用方法想知道它的被调用方法中的异常时,被调用的方法应该包含'throw exception;' Catch块中的声明。

通过这种方式,

@Test
public void test2() 
{
    System.out.println("Within test2");
    int a = 12;
    int b =20;

    try 
    {
        Assert.assertEquals(a, b);
    }catch(Exception e)
    {
        System.out.println("Exception Occurred");
        throw e;
    }
}

TestNG会知道,抛出异常。然后,TestNG将失败该方法 请注意,e.printStackTrace();也不会让你的测试用例失败。