Mockito在例外Junit 4.10之后验证 [英] Mockito verify after exception Junit 4.10

查看:169
本文介绍了Mockito在例外Junit 4.10之后验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试一个带有预期异常的方法。我还需要验证在抛出异常后调用了一些清理代码(在模拟对象上),但看起来该验证被忽略了。这是代码。我使用Junit ExpectedException 规则来验证预期的异常。

I am testing a method with an expected exception. I also need to verify that some cleanup code was called (on a mocked object) after the exception is thrown, but it looks like that verification is being ignored. Here is the code. I am using the Junit ExpectedException Rule to verify the expected exception.

@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(...));
}

似乎验证完全被忽略了。无论我在验证中放入什么方法,我的测试都是通过,这不是我想要的。

It seems like the verify is totally being ignored. No matter what method I put in the verify, my test is passing, which is not what I want.

知道为什么会这样吗?

推荐答案

ExpectedException 的工作原理是包装整个测试方法通过 JUnit @Rule 。当你的代码抛出异常时,它会将堆栈上升到最近的try / catch,这恰好在ExpectedException实例中(它检查它是你期望的异常)。

ExpectedException works by wrapping your entire test method in a try-catch block via a JUnit @Rule. When your code throws an exception, it goes up the stack to the nearest try/catch, which happens to be in the ExpectedException instance (which checks that it is the exception you're expecting).

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

In Java, if an uncaught exception occurs in a method, control will never return to statements later in that method. The same rules apply here: Control never returns to the statements in your test after the exception.

从技术上讲,您可以将验证放入最后阻止,但往往是一个坏习惯编辑:您的被测系统可能会抛出一个意外的异常,或者根本没有异常,这会给您一个有用的失败消息和跟踪;但是,如果该失败导致您的验证或断言在 finally 块中失败,那么Java将显示该消息而不是关于意外异常或意外成功的消息。这可能会使调试变得困难,特别是因为您的错误将来自错误根本原因的代码行,错误地暗示其上方的代码成功。

Technically, you could put the verifications in a finally block, but that tends to be a bad habit. Your system-under-test might throw an unexpected exception, or no exception at all, which would give you a helpful failure message and trace; however, if that failure then causes your verifications or assertions to fail in the finally block, then Java will show that rather than a message about the unexpected exception or unexpected success. This can make debugging difficult, especially because your error will come from lines of code following the root cause of the error, incorrectly implying that the code above it succeeded.

如果您确实需要在异常后验证状态,在每个方法的基础上,你总是可以恢复到这个习语:

If you really need to verify state after the exception, on a per-method basis, you can always revert back to this idiom:

@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块中包装函数接口调用简明扼要地足够有用。我想这种语法的支持将进入许多标准测试库。

Update: With Java 8's lambda expressions, you can wrap a functional interface call in a try block concisely enough to be useful. I imagine support for this syntax will find its way into many standard testing libraries.

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

这篇关于Mockito在例外Junit 4.10之后验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆