JUnit测试异常

91
我对Java非常新手。
我正在一个构造函数上运行一些JUnit测试。该构造函数是这样的,如果给定其中一个参数的值为null或空字符串,则应该抛出异常。
当我在JUnit中使用null或空字符串参数测试此构造函数时,即使我几乎100%确定构造函数方法确实在传入这样的参数时抛出异常,我仍然得到了红色条。
如果方法按照预期抛出异常,难道在JUnit中不应该是绿色条吗?或者说,当异常处理按照预期工作时,您应该得到红色条吗?
5个回答

132
@Test(expected = Exception.class)  

告诉Junit预期结果是异常,因此当抛出异常时测试将通过(标记为绿色)。

对于

@Test

如果抛出未检查的异常,Junit将会将测试视为失败。如果是已检查的异常,则无法编译,需要使用其他方法。这个link可能会有所帮助。

但是如何通过这种解决方案传递自定义消息呢?我的业务逻辑是:throw IOException("username can't be null")。我知道org.junit.rules.ExpectedException,但我不想创建一个实例并使用.expect(.expectMessage( - Dr.jacky

47
"我确定你告诉它要期待这个异常了吗?"
"对于较新的JUnit(>=4.7),你可以使用类似以下的代码(来自此处链接)"
@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void testRodneCisloRok(){
    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("error1");
    new RodneCislo("891415",dopocitej("891415"));
}

而对于较旧的JUnit,则是这样:

@Test(expected = ArithmeticException.class)  
public void divisionWithException() {  
  int i = 1/0;
}

如果测试类抛出异常,您可以简单地抛出该异常并测试您编写的 Junit 测试用例,使用 @Test(expected = IllegalArgumentException.class)。 - Janitha Madushan

6
使用ExpectedException规则(版本4.7)的优点在于您可以测试异常消息,而不仅仅是预期的异常。并且使用Matchers,您可以测试您感兴趣的消息部分。
exception.expectMessage(containsString("income: -1000.0"));

6
如果您的构造函数类似于这样:
public Example(String example) {
    if (example == null) {
        throw new NullPointerException();
    }
    //do fun things with valid example here
}

然后,当您运行此JUnit测试时,您将获得一个绿色的进度条:

@Test(expected = NullPointerException.class)
public void constructorShouldThrowNullPointerException() {
    Example example = new Example(null);
}

5

虽然@Test(expected = MyException.class)ExpectedException rule是非常好的选择,但在某些情况下,JUnit3风格的异常捕获仍然是最佳方式:

@Test public void yourTest() {
  try {
    systemUnderTest.doStuff();
    fail("MyException expected.");
  } catch (MyException expected) {

    // Though the ExpectedException rule lets you write matchers about
    // exceptions, it is sometimes useful to inspect the object directly.

    assertEquals(1301, expected.getMyErrorCode());
  }

  // In both @Test(expected=...) and ExpectedException code, the
  // exception-throwing line will be the last executed line, because Java will
  // still traverse the call stack until it reaches a try block--which will be
  // inside the JUnit framework in those cases. The only way to prevent this
  // behavior is to use your own try block.

  // This is especially useful to test the state of the system after the
  // exception is caught.

  assertTrue(systemUnderTest.isInErrorState());
}

另一个声称可以帮助的库是catch-exception;然而,截至2014年5月,该项目似乎处于维护模式(被Java 8淘汰),并且与Mockito一样,catch-exception只能操作非 final 方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接