例外的Junit 4.10后验证的Mockito(Mockito verify after exce

2019-07-03 13:50发布

我测试与预期异常的方法。 我还需要核实一些清理代码被称为(一个嘲笑对象)的异常被抛出之后,但它看起来像核查被忽略。 下面是代码。 我使用JUnit ExpectedException Rule来验证预期的异常。

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

@Test
public void testExpectedException()
{
   MockedObject mockObj = mock(MockedObj.class);
   MySubject subject = new MySubject(mockedObj);
   expectedEx.expect(MyException.class);
   expectedEx.expectMessage("My exception message.");
   subject.someMethodThrowingException();
   verify(mockObj).
       someCleanup(eq(...));
}

这似乎是verify是完全被忽略。 无论我提出什么方法的verify ,我测试合格,这不是我想要的。

任何想法,为什么多数民众赞成happenning?

Answer 1:

ExpectedException工作原理是包裹整个测试方法,通过在try-catch块的JUnit @rule 。 当你的代码抛出一个异常,这是不言而喻的堆栈到最近的try / catch,这恰好是在的ExpectedException实例(检查它是你期待的除外)。

在Java中,如果一个方法发生了未捕获的异常,控制永远不会返回到报表中该方法后。 适用同样的规则在这里: 控制永远不会返回到异常后,测试的语句。

从技术上讲,你可以把验证在finally块,但往往是一个坏习惯 。 编辑:您的系统下测试可能会引发意外的异常,或也不例外可言,它会给你一个有用的失败消息和跟踪; 但是,如果失败则使您的验证和断言在失败finally块,那么Java将显示,而不是一个关于意外的异常或意外成功的消息。 这可以使调试困难,特别是因为你的错误将来自以下错误的根本原因的代码行,错误地暗示其上面的代码成功。

如果你真的需要异常后,验证状态,在每一方法的基础,你可以随时恢复到这个成语:

@Test
public void testExpectedException()
{
  MockedObject mockObj = mock(MockedObj.class);
  MySubject subject = new MySubject(mockedObj);
  try {
    subject.someMethodThrowingException();
    fail("Expected MyException.");
  } catch (MyException expected) {
    assertEquals("My exception message.", expected.getMessage());
  }
  verify(mockObj).someCleanup(eq(...));
}

更新:使用Java 8的Lambda表达式,你可以用在try块的功能接口调用简洁足够有用 。 我想支持这个语法会找到自己的方式为许多标准的测试库。

assertThrows(MyException.class,
    () -> systemUnderTest.throwingMethod());


Answer 2:

用更优雅的解决方案捕获的异常

@Test
public void testExpectedException()
{
    MockedObject mockObj = mock(MockedObject.class);
    MySubject subject = new MySubject(mockObj);

    when(subject).someMethodThrowingException();

    then(caughtException())
            .isInstanceOf(MyException.class)
            .hasMessage("My exception message.");

    verify(mockObj).someCleanup(eq(...));
}


Answer 3:

我没有试过呢,但除了杰夫·鲍曼的出色答卷,您可能需要使用的ExpectedException规则与一个try ... finally结构的选择,把你的验证声明finally块。



Answer 4:

一旦异常被抛出UT,下面所有的代码都将被忽略。

@Test(expected = Exception.class)
public void testExpectedException() {
   MockedObject mockObj = mock(MockedObj.class);
   MySubject subject = new MySubject(mockedObj);
   subject.doSomething(); // If this line results in an exception then all the code below this will be ignored.
   subject.someMethodThrowingException();
   verify(mockObj).
       someCleanup(eq(...));
}

为了解决这个问题,并确认所做的所有来电,我们可以用试图最后

@Test(expected = Exception.class)
    public void testExpectedException() {
          MockedObject mockObj = mock(MockedObj.class);
          MySubject subject = new MySubject(mockedObj);
          try {
               subject.someMethodThrowingException(); 
          } finally {
             verify(mockObj).
             someCleanup(eq(...));
          }
} 


文章来源: Mockito verify after exception Junit 4.10