为什么在junit测试中使用Mockitojunitrunner类? [英] Why we use Mockitojunitrunner class in our junit test?

查看:298
本文介绍了为什么在junit测试中使用Mockitojunitrunner类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是mockito框架的新手,对此我有一个非常基本的问题,为什么我们要在junit测试类中使用 MockitoJunitRunner类.我也发现了与此有关的以下两点,但无法理解,任何人都可以详细解释以下两点

I am new in mockito framework, and I have a very basic question regarding this, why exactly we are using MockitoJunitRunner class in our junit test class. Also I found the following two points related to this but couldn't get it, can any one explains following two points in detail

自动验证框架使用情况确实值得.如果您犯了这些错误之一,它可以为您提供更好的报告.

The automatic validation of framework usage is actually worth having. It gives you better reporting if you make one of these mistakes.

  • 您在模拟程序上调用verify,但是忘记提供该方法调用 您正在尝试验证.
  • 您调用when方法之一(静态方法或方法之一) 在doReturn,doThrow或doAnswer之后)并传递了一个模拟,但忘记了 提供您要存根的方法.
  • You call verify on a mock, but forget to provide the method call that you are trying to verify.
  • You call one of the when methods (either the static one, or the one after doReturn, doThrow or doAnswer) and pass a mock, but forget to provide the method that you are trying to stub.

推荐答案

使用MockitoJunitRunner而不是JunitRunner确实是可选的.

Using MockitoJunitRunner rather than JunitRunner is really optional.

自动验证框架使用情况确实值得. 如果您犯了这些错误之一,它可以为您提供更好的报告.

The automatic validation of framework usage is actually worth having. It gives you better reporting if you make one of these mistakes.

MockitoJunitRunner提供的主要优点是,当您使用@Mock方法创建模拟时,可以减轻您显式调用MockitoAnnotations.initMocks(Object)的麻烦.

The main advantage provided by MockitoJunitRunner is relieving you to explicitly invoke MockitoAnnotations.initMocks(Object) when you use the @Mock way to create your mocks.

但是通过使用此运行器,您可能还会得到一些有关Mockito框架的滥用报告,而如果不使用它,可能会丢失.

But you could also get a few more misuse reports of the Mockito framework by using this runner that may be missing without using it.

Mockito 1.10.19版本的Javadoc指出:

The javadoc of the Mockito 1.10.19 version states :

与JUnit 4.4和更高版本兼容,此运行器添加了以下内容 行为:

Compatible with JUnit 4.4 and higher, this runner adds following behavior:

  • 初始化带有Mock注释的模拟,以便显式使用 MockitoAnnotations.initMocks(Object)不是必需的.嘲笑是 在每种测试方法之前进行初始化.

  • Initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.

在每种测试方法之后验证框架使用情况.参见javadoc Mockito.validateMockitoUsage().

validates framework usage after each test method. See javadoc for Mockito.validateMockitoUsage().

最重要的部分:

Runner完全是可选的-还有其他方法可以获取@Mock 工作,例如通过编写基类. 明确验证 框架用法也是可选的,因为它是自动触发的 每次使用框架时,由Mockito撰写.有关详细信息,请参见javadoc Mockito.validateMockitoUsage().

Runner is completely optional - there are other ways you can get @Mock working, for example by writing a base class. Explicitly validating framework usage is also optional because it is triggered automatically by Mockito every time you use the framework. See javadoc for Mockito.validateMockitoUsage().

在不使用MockitoJunitRunner的情况下开箱即用的不正确用法示例:

Example of incorrect uses that may be caught out of the box without using the MockitoJunitRunner :

 //Oops, thenReturn() part is missing:
 when(mock.get());

 //Oops, verified method call is inside verify() where it should be on the outside:
 verify(mock.execute());

 //Oops, missing method to verify:
 verify(mock);

但是不能在所有情况下都发现它们.

But these could not be caught in all cases.

由运行器和框架本身调用的Mockito.validateMockitoUsage()方法提供了有关它的更多说明,但实际上它并不完整.

The Mockito.validateMockitoUsage() method that is invoked by the runner and the framework itself gives more explanations about it but in fact it is not complete.

validateMockitoUsage()明确验证框架状态为 检测到无效的Mockito使用.但是,此功能是可选的 因为Mockito一直在验证使用情况... 但是有一个 请继续阅读.

validateMockitoUsage() explicitly validates the framework state to detect invalid use of Mockito. However, this feature is optional because Mockito validates the usage all the time... but there is a gotcha so read on.

好的.继续.

如果误用了Mockito,则会抛出异常,以便您知道 测试编写正确.陷阱是,Mockito会做 再次下次验证您使用该框架(例如,下次您进行验证时, 存根,调用模拟等).但是即使可能会引发异常 在下一个测试中,异常消息包含一个可导航的堆栈 痕迹元素以及缺陷的位置.因此,您可以单击和 找到滥用Mockito的地方.

Mockito throws exceptions if you misuse it so that you know if your tests are written correctly. The gotcha is that Mockito does the validation next time you use the framework (e.g. next time you verify, stub, call mock etc.). But even though the exception might be thrown in the next test, the exception message contains a navigable stack trace element with location of the defect. Hence you can click and find the place where Mockito was misused.

因此,该框架在您下次使用该框架时进行验证(验证,存根,调用模拟等).
实际上,这是事实,但并非总是如此.

So, the framework does the validation the next time you use the framework (verify, stub, call mock,etc..).
In fact it is true but not always.

例如,这种滥用将被框架捕获:

For example this misuse will be caught by the framework :

@Test
public void testBadUseWhen() throws Exception {
   Address mock = Mockito.mock(Address.class);
   Mockito.verify(mock.getAddressLine());
}

org.mockito.exceptions.misusing.NullInsteadOfMockException:参数 传递给verify()应该是模拟的,但为空!

org.mockito.exceptions.misusing.NullInsteadOfMockException: Argument passed to verify() should be a mock but is null!

但是不会发现这种滥用:

But this misuse will not be caught :

@Test
public void testBadUseWhen() throws Exception {
  Address mock = Mockito.mock(Address.class);
  Mockito.when(mock.getAddressLine());
}

当我在未发现的滥用情况下添加新的Mockito用法时,这次我们将收到一个验证异常:

While if I add a new use of Mockito after this uncaught misuse, this time we will get a validation exception :

@Test
public void testBadUseWhen() throws Exception {
    Address mock = Mockito.mock(Address.class); 
    Mockito.when(mock.getAddressLine());
    Mockito.when(mock.getAddressLine());
}

org.mockito.exceptions.misusing.UnfinishedStubbingException: 在此处检测到未完成的存根

org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here

它将为第二个调用的Mockito.when(mock.getAddressLine());语句引发,但异常将引用第一个调用的Mockito.when(mock.getAddressLine());语句.

It will be raised for the second Mockito.when(mock.getAddressLine()); statement invoked but the exception will reference the first Mockito.when(mock.getAddressLine()); statement invoked.

这意味着对于框架的某些错误使用,如果使用的最后一个Mockito方法使用不正确,则可能会丢失报告信息.

It means that for some bad uses of the framework, you could lose the report information if the last mockito method you are used is incorrectly used.

然后Javadoc指出:

The javadoc states then :

有时候,您可能想验证框架的用法 明确地.举例来说,其中一位使用者想放 validateMockitoUsage()在他的@After方法中,以便他知道 当他滥用Mockito时,立即.没有它,他会知道 关于此问题,他不早于下一次就使用了该框架.多一个 @After中具有validateMockitoUsage()的好处是jUnit 跑步者和规则总是会在有缺陷的测试方法中失败 而普通的下次"验证可能无法通过下次测试 方法.但是,即使JUnit可能会将下一个测试报告为红色,也不要 担心它,只需单击 异常消息可立即找到您滥用的地方 模仿.

Sometimes though, you might want to validate the framework usage explicitly. For example, one of the users wanted to put validateMockitoUsage() in his @After method so that he knows immediately when he misused Mockito. Without it, he would have known about it not sooner than next time he used the framework. One more benefit of having validateMockitoUsage() in @After is that jUnit runner and rule will always fail in the test method with defect whereas ordinary 'next-time' validation might fail the next test method. But even though JUnit might report next test as red, don't worry about it and just click at navigable stack trace element in the exception message to instantly locate the place where you misused mockito.

因此,为了不丢失测试类中最后一个调用的Mockito方法的潜在滥用,您可以在每个经过测试的方法后显式调用Mockito.validateMockitoUsage().

So, to not loosing a potentially misuse for the last one Mockito method invoked during a test class, you can explicitly invoke Mockito.validateMockitoUsage() after each tested method.

所以这可以解决问题:

@After
public void after() {
    Mockito.validateMockitoUsage();
}

替代方法是使用MockitoJUnitRunner,在每次执行的测试后,引擎盖下都会调用Mockito.validateMockitoUsage():

The alternative is using the MockitoJUnitRunner that under the hood invokes Mockito.validateMockitoUsage() after each executed test :

@Override
public void testFinished(Description description) throws Exception {
    super.testFinished(description);
    try {
        Mockito.validateMockitoUsage();
    } catch(Throwable t) {
        notifier.fireTestFailure(new Failure(description, t));
    }
}

这篇关于为什么在junit测试中使用Mockitojunitrunner类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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