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

时间:2013-04-26 19:08:53

标签: java exception-handling junit mockito

我在junit测试中使用mockito。如何使异常发生,然后声明它具有(通用伪代码)

12 个答案:

答案 0 :(得分:173)

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

注释您的测试
@Test(expected=MyException.class)

断言发生了异常。要使用mockito“模拟”异常,请使用

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

答案 1 :(得分:64)

BDD样式解决方案(已更新至Java 8)

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

Mockito + Catch-Exception + AssertJ

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

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

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

示例代码

依赖关系

答案 2 :(得分:20)

如果你想测试异常消息,你也可以使用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"));
}

答案 3 :(得分:15)

使异常发生如下:

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

通过断言你的测试会抛出这样的异常来验证它是否已经发生:

@Test(expected = AnException.class)

或通过正常的模拟验证:

verify(obj).someMethod();

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

答案 4 :(得分:12)

如果您使用的是JUnit 4和Mockito 1.10.x. 使用以下命令注释您的测试方法:

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

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

{{1}}

答案 5 :(得分:10)

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

答案 6 :(得分:3)

使用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);
}

答案 7 :(得分:1)

使用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());
}

在此处查找示例:assert exception junit

答案 8 :(得分:1)

我认为这应该适合你。

assertThrows(someException.class, ()-> mockedServiceReference.someMethod(param1,parme2,..));

答案 9 :(得分:0)

与mockito无关,可以捕获异常并声明其属性。要验证异常确实发生,请在抛出异常的语句之后在try块中声明false条件。

答案 10 :(得分:0)

或者如果您的异常是从类的构造函数中抛出的:

const child_process = require('child_process');
/* ... */
function compileThreeFiles(dirPath, req, res) {
  child_process.exec(`javac ${dirPath}NodeJsInput.java`, (err) => {
    if (err) {
      console.log(err);
      res.json(resJson);
      return;
    }
    setTimeout(function() {
      child_process.exec(`javac ${dirPath}Robot.java`, (err) => {
        if (err) {
          console.log(err);
          res.json(resJson);
          return;
        }
        setTimeout(function() {
          child_process.exec(`javac ${dirPath}Main.java`, (err) => {
            if (err) {
              console.log(err);
              res.json(resJson);
              return;
            }
            setTimeout(function() {
              executeMain(dirPath, req, res);
            }, 10000);
          });
        }, 10000);
      });
    }, 10000);
  });
}

答案 11 :(得分:-1)

异常消息断言:

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