替代@Test(expected = ExceptionClass.class)来测试testng中的异常

时间:2015-11-15 07:51:00

标签: java unit-testing junit testng

在TestNG中,当我们想要测试应该抛出异常的场景时,可以编写类似下面的内容

@Test(expected=IndexOutOfBoundsException.class, expectedExceptionsMessageRegExp="*")
public void sampleExpectedExceptionTest() {
    List emptyList = new ArrayList();
    // Following line should throw an IndexOutOfBoundsException
    emptyList.get(0);
} 

我看到有些人以下列风格编写测试。

@Test
public void sampleExpectedExceptionTest() {
  // several lines here..

  List emptyList = new ArrayList();
  try {
    emptyList.get(0);
    Assert.assertFail("Expected IndexOutOfBoundsException but wasn't thrown");
  } catch (IndexOutOfBoundsException e) {
    // ignore
  }

  // ... more lines of code asserting exceptions similar to above try catch scenario
}

我不喜欢上述风格,主要是因为它非常冗长,而且因为使用它的人通常会在一个测试用例中编写多个测试。然而,它所支持的论点是它允许用户查明特定行的断言,因此它更好。

最近我了解了JUnit的@Rule注释

public class SampleExceptionTest {
   @Rule
   public final ExpectedException exception = ExpectedException.none();

   @Test
   public void sampleExpectedExceptionTest() {
       List emptyList = new ArrayList();

       exception.expect(IndexOutOfBoundsException.class);
       emptyList.get(0);
   }
}

这不仅允许用户查明对一行的断言,而且还阻止用户在一个测试用例中编写多个测试,因为一旦异常被抛出,代码退出并且您无法测试多个断言。我想知道TestNG中是否有类似的选项(或成语)?我知道我可以使用预期的

1 个答案:

答案 0 :(得分:1)

我建议您查看Catch-Exception库。它允许您对异常和任何其他相关断言执行多个断言。您可以将它与JUnit和TestNG以及您想要的任何断言框架一起使用。

样品:

@Test
public void catchExceptionTest() {
    // given: an empty list
    List<Object> myList = new ArrayList<>();

    // when: we try to get the first element of the list
    // then: catch the exception if any is thrown
    catchException(myList).get(1);

    // then: we expect an IndexOutOfBoundsException
    Exception e = caughtException();
    // Use JUnit, TestNG, AssertJ etc. assertions on the "e" exception
    assert e instanceof IndexOutOfBoundsException;
}

您可以在项目页面上找到更多示例。