是否没有必要验证与 Mockito 中被模拟的方法相同的方法? [英] Is it unnecessary to verify the same methods as the methods being mocked in Mockito?

查看:44
本文介绍了是否没有必要验证与 Mockito 中被模拟的方法相同的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常看到与在 Mockito 中模拟的方法相同的方法被验证(下面的示例).在这些情况下调用 Mockito.verify() 有什么额外的好处吗?

I often see the same methods being verified as the methods being mocked in Mockito (example below). Is there any added benefit to call Mockito.verify() in these cases?

//mock method
FooService fs = mock(FooService.class);
when(fs.getFoo()).thenReturn("foo");

//method under test
fs.doSomething();

//verify method
verify(fs).getFoo();

如果 fs.getFoo() 没有被调用,该方法应该会失败.那么为什么要调用 verify 呢?如果您需要在验证中使用 ArgumentCaptor 来断言参数,我会看到好处;除了 ArgumentCaptor 案例,它只是没有必要吗?

The method should fail if fs.getFoo() is not called. So why call verify? I see the benefit if you need to use ArgumentCaptor in the verify to assert the parameters; besides the ArgumentCaptor case, is it just unnecessary?

推荐答案

Mockito 文档反复说它通常是多余的.这在 verify(T) 中逐字显示Javadoc 作为 Mockito 的主要代码块中的多个单行注释类 Javadoc 部分 2:

The Mockito documentation repeatedly says it is often redundant. This appears verbatim both in verify(T)'s Javadoc as multiple single-line comments in the code block in Mockito's main class Javadoc section 2:

虽然可以验证存根调用,但通常它只是多余的.如果你的代码关心 get(0) 返回什么,那么其他东西就会中断(通常甚至在 verify() 被执行之前).如果你的代码不关心 get(0) 返回什么,那么它不应该被存根.不服气?请参阅此处.

Although it is possible to verify a stubbed invocation, usually it's just redundant. If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed). If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.

请注意,链接的文章提问和讲述"是 Mockito 创始人撰写的Szczepan Faber 并且可以被认为是 Mockito 设计中的权威文档.摘自该帖子:

Note that the linked article, "Asking and Telling", was written by Mockito originator Szczepan Faber and can be considered an authoritative document in Mockito's design. To excerpt from that post:

我真的需要重复同样的表达吗?毕竟,存根交互是隐式验证.我自己代码的执行流程完全免费.Aaron Jensen还注意到:

Do I really have to repeat the same expression? After all, stubbed interactions are verified implicitly. The execution flow of my own code does it completely for free. Aaron Jensen also noticed that:

如果您正在验证,则不需要存根,除非该方法返回对测试(或代码)流程至关重要的内容,在这种情况下,您实际上不需要验证,因为流程会得到验证.

If you’re verifying you don’t need to stub unless of course that method returns something that is critical to the flow of your test (or code), in which case you don’t really need to verify, because the flow would have verified.

总结一下:没有重复的代码.

但是,如果一个有趣的交互具有询问和告知的特征呢?我是否必须在 stub() 和 verify() 中重复交互?我最终会得到重复的代码吗?并不真地.在实践中:如果我存根,那么它是免费验证的,所以我不验证.如果我验证,那么我不关心返回值,所以我不存根.无论哪种方式,我不重复自己.不过在理论上,我可以想象一种罕见的情况,我确实验证了存根交互,例如确保存根交互恰好发生了 n 次.但这是行为的不同方面,显然是一个有趣的方面.因此,我想明确一点,我非常乐意牺牲额外的一行代码……

But what if an interesting interaction shares the characteristic of both asking and telling? Do I have to repeat interactions in stub() and verify()? Will I end up with duplicated code? Not really. In practice: If I stub then it is verified for free, so I don’t verify. If I verify then I don’t care about the return value, so I don’t stub. Either way, I don’t repeat myself. In theory though, I can imagine a rare case where I do verify a stubbed interaction, for example to make sure the stubbed interaction happened exactly n times. But this is a different aspect of behavior and apparently an interesting one. Therefore I want to be explicit and I am perfectly happy to sacrifice one extra line of code…

总的来说,Mockito 的设计是让测试尽可能灵活,编码不是针对实现而是针对您正在测试的方法的规范.尽管您偶尔会看到一个方法调用作为函数规范的一部分(向服务器提交 RPC"或立即调用传递的 LoginCallback"),但您更有可能想要验证您可以使用的后置条件从存根推断:只要您存根 getFoo 返回foo"并且数据存储包含一个将其相应属性设置为foo"的单个对象.

Overall, Mockito's design is to allow tests to be as flexible as possible, coding not to the implementation but instead to the spec of the method you're testing. Though you'll occasionally see a method call as part of a function's spec ("Submits an RPC to the server" or "Calls the passed LoginCallback immediately"), it's much more likely that you'll want to validate the postconditions that you can infer from the stubs: Checking that getFoo was called isn't really a part of the spec as long as you stubbed getFoo to return "foo" and the data store contains a single object with its corresponding property set to "foo".

简而言之,仅显式验证无法从精心设计的存根和后置断言中隐含的交互被认为是良好的 Mockito 风格.它们可能很好地调用了其他无法衡量的副作用——记录代码、线程执行器、ArgumentCaptor、多个方法调用、回调函数——但通常不应用于存根交互.

In short, it is considered good Mockito style to explicitly verify only the interactions that can't be implied from well-crafted stubs and postcondition assertions. They may be good calls for otherwise-unmeasurable side effects—logging code, thread executors, ArgumentCaptors, multiple method calls, callback functions—but generally should not be applied to stubbed interactions.

这篇关于是否没有必要验证与 Mockito 中被模拟的方法相同的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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