如何模拟和断言抛出的异常?

我在一个联合测试中用了麻醉剂。如何使异常发生,然后断言它具有(泛型伪代码)

538051 次浏览

如果您使用的是 JUnit4,那么您可以使用

@Test(expected=MyException.class)

断言一个异常已经发生。要“模仿”一个异常,使用

when(myMock.doSomething()).thenThrow(new MyException());

例外情况是这样的:

when(obj.someMethod()).thenThrow(new AnException());

通过断言测试将抛出这样一个异常来验证它是否已经发生:

@Test(expected = AnException.class)

或者通过正常的模拟验证:

verify(obj).someMethod();

如果您的测试旨在证明中间代码可以处理异常(即异常不会从测试方法中抛出) ,则需要后一个选项。

BDD 样式解决方案(更新至 Java8)

单独使用 Mockito 不是处理异常的最佳解决方案,使用 莫基托接球-例外

Mockito + 接球-例外 + 断言

given(otherServiceMock.bar()).willThrow(new MyException());


when(() -> myService.foo());


then(caughtException()).isInstanceOf(MyException.class);

样本代码

依赖性

2015年6月19日更新答案(如果你使用 java 8)

使用 assertj

使用 assertj-core-3.0.0 + Java 8 Lambdas

@Test
public void shouldThrowIllegalArgumentExceptionWhenPassingBadArg() {
assertThatThrownBy(() -> myService.sumTingWong("badArg"))
.isInstanceOf(IllegalArgumentException.class);
}

参考资料: http://blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html

如果您使用的是 JUnit4和 Mockito 1.10. x 对测试方法进行如下注释:

@Test(expected = AnyException.class)

并抛出所需的异常使用:

Mockito.doThrow(new AnyException()).when(obj).callAnyMethod();

如果您也想测试异常消息,可以使用 JUnit 的 ExpectedException 和 Mockito:

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


@Test
public void testExceptionMessage() throws Exception {
expectedException.expect(AnyException.class);
expectedException.expectMessage("The expected message");


given(foo.bar()).willThrow(new AnyException("The expected message"));
}

使用模拟器,可以使异常发生。

when(testingClassObj.testSomeMethod).thenThrow(new CustomException());

使用 Junit5,可以断言异常,断言在调用 测试方法时是否引发 那个异常。

@Test
@DisplayName("Test assert exception")
void testCustomException(TestInfo testInfo) {
final ExpectCustomException expectEx = new ExpectCustomException();


InvalidParameterCountException exception = assertThrows(InvalidParameterCountException.class, () -> {
expectEx.constructErrorMessage("sample ","error");
});
assertEquals("Invalid parametercount: expected=3, passed=2", exception.getMessage());
}

在这里找到一个样本: 断言异常连接

与仿真无关,可以捕捉异常并断言其属性。要验证异常是否确实发生,请在引发异常的语句之后的 try 块中断言一个假条件。

通过异常消息进行断言:

    try {
MyAgent.getNameByNode("d");
} catch (Exception e) {
Assert.assertEquals("Failed to fetch data.", e.getMessage());
}

或者如果异常是从类的构造函数引发的:

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


@Test
public void myTest() {


exception.expect(MyException.class);
CustomClass myClass= mock(CustomClass.class);
doThrow(new MyException("constructor failed")).when(myClass);


}

使用 Mockito’s doThrow,然后捕获所需的异常,以断言它是以后抛出的。

@Test
public void fooShouldThrowMyException() {
// given
val myClass = new MyClass();
val arg = mock(MyArgument.class);
doThrow(MyException.class).when(arg).argMethod(any());
Exception exception = null;


// when
try {
myClass.foo(arg);
} catch (MyException t) {
exception = t;
}


// then
assertNotNull(exception);
}

我觉得这个应该够了。

AssertThrows (some Exception.class, ()-> modedServiceReference.some 方法(parme2,. .) ;

对我来说,一个简单而简短的方法是:

assertThrows(YourException.class, () -> yourLogic())