我知道有一种方法是:

@Test
public void foo() {
   try {
      // execute code that you expect not to throw Exceptions.
   } catch(Exception e) {
      fail("Should not have thrown any exception");
   }
}

还有更干净的方法吗?(可能使用了Junit的@Rule?)


当前回答

如果您想测试您的测试目标是否使用异常。只需要将测试保留为(使用jMock2的模拟合作者):

@Test
public void consumesAndLogsExceptions() throws Exception {

    context.checking(new Expectations() {
        {
            oneOf(collaborator).doSth();
            will(throwException(new NullPointerException()));
        }
    });

    target.doSth();
 }

如果您的目标确实使用抛出的异常,则测试将通过,否则测试将失败。

如果您想测试异常使用逻辑,事情会变得更加复杂。我建议将消费委托给一个可能被嘲笑的合作者。因此,测试可以是:

@Test
public void consumesAndLogsExceptions() throws Exception {
    Exception e = new NullPointerException();
    context.checking(new Expectations() {
        {
            allowing(collaborator).doSth();
            will(throwException(e));

            oneOf(consumer).consume(e);
        }
    });

    target.doSth();
 }

但如果你只是想记录它,有时它就设计过度了。在这种情况下,如果您坚持使用tdd,本文(http://java.dzone.com/articles/monitoring-declarative-transac, http://blog.novoj.net/2008/09/20/testing-aspect-pointcuts-is-there-an-easy-way/)可能会有所帮助。

其他回答

我遇到了同样的情况,我需要检查异常是否在应该抛出的时候抛出,并且仅在应该抛出的时候抛出。 最终使用异常处理程序对我的好处如下代码:

    try {
        functionThatMightThrowException()
    }catch (Exception e){
        Assert.fail("should not throw exception");
    }
    RestOfAssertions();

对我来说,主要的好处是它非常直截了当,并且在相同的结构中检查“如果且仅当”的另一种方式非常容易

JUnit 5 (Jupiter)提供了三个函数来检查异常是否存在:

● 断言全部()

断言所有提供的可执行文件 不要抛出异常。

● assertDoesNotThrow()

类的执行 提供可执行/供应商 不抛出任何类型的异常。

此函数可用 JUnit 5.2.0以来(2018年4月29日)。

●assertThrows ()

断言所提供的可执行文件的执行 抛出expectedType的异常 并返回异常。

例子

package test.mycompany.myapp.mymodule;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class MyClassTest {

    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw() {
        String myString = "this string has been constructed";
        assertAll(() -> MyClass.myFunction(myString));
    }
    
    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw__junit_v520() {
        String myString = "this string has been constructed";
        assertDoesNotThrow(() -> MyClass.myFunction(myString));
    }

    @Test
    void when_string_is_null_then_myFunction_throws_IllegalArgumentException() {
        String myString = null;
        assertThrows(
            IllegalArgumentException.class,
            () -> MyClass.myFunction(myString));
    }

}

你可以基于junit的断言创建你自己的任何类型的断言,因为这些断言是专门为创建用户定义的断言而设计的,其工作方式与junit的断言完全一样:

static void assertDoesNotThrow(Executable executable) {
    assertDoesNotThrow(executable, "must not throw");
}
static void assertDoesNotThrow(Executable executable, String message) {
    try {
        executable.execute();
    } catch (Throwable err) {
        fail(message);
    }
}

现在测试所谓的场景methodMustNotThrow,并以junit风格记录所有失败:

//test and log with default and custom messages
//the following will succeed
assertDoesNotThrow(()->methodMustNotThrow(1));
assertDoesNotThrow(()->methodMustNotThrow(1), "custom facepalm");
//the following will fail
assertDoesNotThrow(()->methodMustNotThrow(2));
assertDoesNotThrow(()-> {throw new Exception("Hello world");}, "message");
//See implementation of methodMustNotThrow below

一般来说,在任何场景中,只要调用fail(someMessage)是有意义的,就有可能立即使测试中的任何内容失败,而fail(someMessage)正是为此目的而设计的。例如,在try/catch块中使用它,如果在测试用例中抛出任何东西,就会失败:

try{methodMustNotThrow(1);}catch(Throwable e){fail("must not throw");}
try{methodMustNotThrow(1);}catch(Throwable e){Assertions.fail("must not throw");}

这是我们测试的方法的样本,假设我们有这样一个方法,在特定的情况下一定不会失败,但它可以失败:

void methodMustNotThrow(int x) throws Exception {
    if (x == 1) return;
    throw new Exception();
}

上述方法是一个简单的示例。但这适用于复杂的情况,在这种情况下,失败不是那么明显。 这里有进口:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.*;

虽然这篇文章已经发布6年了,但是Junit世界已经发生了很多变化。现在可以使用Junit5

org.junit.jupiter.api.Assertions.assertDoesNotThrow()

Ex:

public void thisMethodDoesNotThrowException(){
   System.out.println("Hello There");
}

@Test
public void test_thisMethodDoesNotThrowException(){
  org.junit.jupiter.api.Assertions.assertDoesNotThrow(
      ()-> thisMethodDoesNotThrowException()
    );
}

希望它能帮助那些正在使用Junit5新版本的人

AssertJ可以处理这种情况:

assertThatNoException().isThrownBy(() -> System.out.println("OK"));

查看文档了解更多信息https://assertj.github.io/doc/#assertj-core-exception-assertions-no-exception