如何使用JUnit来测试某些代码是否抛出异常?

我当然可以这样做:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

我记得,对于这类情况,有一个注释或Assert.xyz之类的东西远没有JUnit那么笨拙,更符合JUnit的精神。


当前回答

try {
    my method();
    fail( "This method must thrwo" );
} catch (Exception ex) {
    assertThat(ex.getMessage()).isEqual(myErrormsg);
}

其他回答

我想评论一下这个问题的解决方案,它避免了任何与异常相关的JUnit代码。

我使用assertTrue(布尔值)和try/catch组合来查找要抛出的预期异常。下面是一个示例:

public void testConstructor() {
    boolean expectedExceptionThrown;
    try {
        // Call constructor with bad arguments
        double a = 1;
        double b = 2;
        double c = a + b; // In my example, this is an invalid option for c
        new Triangle(a, b, c);
        expectedExceptionThrown = false; // because it successfully constructed the object
    }
    catch(IllegalArgumentException e) {
        expectedExceptionThrown = true; // because I'm in this catch block
    }
    catch(Exception e) {
        expectedExceptionThrown = false; // because it threw an exception but not the one expected
    }
    assertTrue(expectedExceptionThrown);
}

您也可以这样做:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
    try {
        foo.doStuff();
        assert false;
    } catch (IndexOutOfBoundsException e) {
        assert true;
    }
}

在junit中,有四种方法可以测试异常。

六月5.x

对于junit5.x,可以使用assertThrows,如下所示@测试public void testFooThrowsIndexOutOfBoundsException(){抛出异常=assertThrows(IndexOutOfBoundsException.class,()->foo.doStuff());assertEquals(“预期消息”,exception.getMessage());}

六月4.x

对于junit4.x,使用测试注释的可选“expected”属性@测试(应为IndexOutOfBoundsException.class)public void testFooThrowsIndexOutOfBoundsException(){foo.doStuff();}对于junit4.x,请使用ExpectedException规则公共类XxxTest{@规则引发了public ExpectedException=ExpectedException.none();@测试public void testFooThrowsIndexOutOfBoundsException(){引发.预期(IndexOutOfBoundsException.class)//您可以像这样测试异常消息抛出.expectMessage(“预期消息”);foo.doStuff();}}您还可以使用junit3框架下广泛使用的经典try/catch方法@测试public void testFooThrowsIndexOutOfBoundsException(){尝试{foo.doStuff();fail(“未发生预期的异常。”);}catch(IndexOutOfBoundsException e){//如果执行到达这里,//它表示发生了此异常。//所以我们不需要处理它。}}所以如果你喜欢junit 5,那么你应该喜欢第一个当您只想测试异常类型时,使用第二种方法当需要进一步测试异常消息时,使用前两个和后两个如果您使用junit 3,则首选第四个有关详细信息,您可以阅读本文档和junit5用户指南。

这样如何:捕获一个非常普通的异常,确保它从catch块中取出,然后断言该异常的类是您期望的。如果a)异常类型错误(例如,如果您使用了空指针),并且b)该异常从未被抛出,则该断言将失败。

public void testFooThrowsIndexOutOfBoundsException() {
  Throwable e = null;

  try {
    foo.doStuff();
  } catch (Throwable ex) {
    e = ex;
  }

  assertTrue(e instanceof IndexOutOfBoundsException);
}

例如,您想为下面提到的代码片段编写Junit

public int divideByZeroDemo(int a,int b){

    return a/b;
}

public void exceptionWithMessage(String [] arr){

    throw new ArrayIndexOutOfBoundsException("Array is out of bound");
}

上面的代码用于测试可能发生的某些未知异常,下面的代码用于使用自定义消息断言某些异常。

 @Rule
public ExpectedException exception=ExpectedException.none();

private Demo demo;
@Before
public void setup(){

    demo=new Demo();
}
@Test(expected=ArithmeticException.class)
public void testIfItThrowsAnyException() {

    demo.divideByZeroDemo(5, 0);

}

@Test
public void testExceptionWithMessage(){


    exception.expectMessage("Array is out of bound");
    exception.expect(ArrayIndexOutOfBoundsException.class);
    demo.exceptionWithMessage(new String[]{"This","is","a","demo"});
}