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

sta*_*low 120 java junit exception-handling mockito

我在junit测试中使用mockito.你怎么做一个异常发生然后断言它有(通用伪代码)

Nil*_*lsH 196

首先回答你的第二个问题.如果您使用的是JUnit 4,则可以使用

@Test(expected=MyException.class)
Run Code Online (Sandbox Code Playgroud)

断言发生了异常.并使用mockito"模拟"异常

when(myMock.doSomething()).thenThrow(new MyException());
Run Code Online (Sandbox Code Playgroud)

  • 当您测试具有某种状态的对象的方法时,这种方法是不可接受的。例如,如果您第二次调用它,则有一个对象方法会引发异常。并且您需要测试以测试它在第二个方法调用期间是否抛出异常,而不是在第一个方法调用期间。如果它在第一个方法调用期间(在准备阶段)抛出 MyException,那么它应该无法通过测试。但是使用这种方法,我们无法检查在哪个方法调用期间抛出了异常。 (4认同)

Mar*_*szS 70

BDD风格解决方案

单独的Mockito不是处理异常的最佳解决方案,使用MockitoCatch-Exception

Mockito + Catch-Exception + AssertJ

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

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

then(caughtException()).isInstanceOf(MyException.class);
Run Code Online (Sandbox Code Playgroud)

示例代码

依赖

  • eu.codearte.catch的异常:捕获的异常:1.3.3
  • org.assertj:assertj核心:1.7.0

坏处

  • 仅支持Mockito高达1.10.8

  • 什么是“捕获异常”?有链接吗? (3认同)

Dan*_*ber 23

如果你想测试异常消息,可以使用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"));
}
Run Code Online (Sandbox Code Playgroud)

  • 来自模拟核心:https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/BDDMockito.html (2认同)

Dun*_*nes 16

使异常发生如下:

when(obj.someMethod()).thenThrow(new AnException());
Run Code Online (Sandbox Code Playgroud)

通过声明您的测试将抛出此类异常来验证它是否已发生:

@Test(expected = AnException.class)
Run Code Online (Sandbox Code Playgroud)

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

verify(obj).someMethod();
Run Code Online (Sandbox Code Playgroud)

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


Sel*_*wyn 15

更新了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);
}
Run Code Online (Sandbox Code Playgroud)

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


小智 15

我认为这应该适合你。

assertThrows(someException.class,
()-> mockedServiceReference.someMethod(param1,parme2,..));
Run Code Online (Sandbox Code Playgroud)


小智 14

如果你正在使用JUnit 4和Mockito 1.10.x使用以下方法注释你的测试方法:

@Test(expected = AnyException.class)
Run Code Online (Sandbox Code Playgroud)

并抛出你想要的异常使用:

Mockito.doThrow(new AnyException()).when(obj).callAnyMethod();
Run Code Online (Sandbox Code Playgroud)


Anu*_*dda 7

使用 mockito,您可以使异常发生。

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());
}
Run Code Online (Sandbox Code Playgroud)

在此处查找示例:断言异常 junit


bel*_*lal 6

对我有用的简单而简短的方法是:

assertThrows(YourException.class, () -> yourLogic())
Run Code Online (Sandbox Code Playgroud)


Rod*_*ins 5

使用Mockito的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);
}
Run Code Online (Sandbox Code Playgroud)