gpt4 book ai didi

java - 为 Mockito 创建自定义 VerificationMode 类

转载 作者:行者123 更新时间:2023-11-30 04:11:41 25 4
gpt4 key购买 nike

我想使用 Mockito 验证一些事情,但研究文档让我相信,如果不使用常用的 Mockito 工具,这是不可能的。以此为例:

DrawTool tool = mock(DrawTool.class);
new Drawer().draw(tool);
verify(tool).begin(); // Make sure begin and end are called exactly once each
verify(tool).end();
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();
inOrder.verifyNoMoreInteractions();

这个测试很好地验证了几件事,例如验证 flush 是最后一次交互,但 Mockito 似乎无法验证 begin 是第一次交互。我对 Mockito 工具的不对称性感到惊讶,因此我正在研究创建自定义验证模式的可能性。我想创建一个名为 beforeAnyOther 的 VerificationMode 并像这样使用它:

inOrder.verify(tool, beforeAnyOther()).begin();
inOrder.verify(tool).end();
inOrder.verify(tool, beforeAnyOther()).flush();
inOrder.verifyNoMoreInteractions();

目的是验证 begin 是否首先被调用,并且 endflush 之间没有相关交互,同时保留交互beginend 之间未指定。

我一直在研究现有 VerificationModes 的源代码,似乎原则上这应该是一个简单的 VerificationMode 来实现,但是一旦我超越了 Mockito 的一些主要类,文档就变得非常薄弱,几乎就像它在尝试一样告诉我我不应该碰这些类(class)。我特别警惕以 org.mockito.internal 开头的包,因为这样的名称对我来说意味着这些类即使是公共(public)的,也可能会发生更改。

实现VerificationMode真正重要的类似乎都在org.mockito.internal.verification.api包中。整个包似乎只有一点 javadoc,它说:“一旦验证 API 完全完成,这个包就应该向公众开放。”这是否意味着这个包正在被积极修改,所以我不应该使用它包含的任何内容,或者这只是它多年来所说的内容,并且该包可能永远不会真正改变?

如果我无法使用 org.mockito.internal.verification.api 中的类,那么似乎不可能实现自定义 VerificationModes。有没有办法在没有自定义 VerificationModes 的情况下执行类似的操作?

最佳答案

如果您可以完全指定模拟上将发生的调用顺序,那么您将不需要 beforeAnyOther 验证模式。例如,假设您想要的行为是...

  • begin 被调用一次,然后
  • end 被调用一次,然后
  • flush 被调用一次
  • 没有对工具进行其他调用

那么以下应该是工作:

// Verify that the three invocations arrived in the desired order.
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();

// Verify that the three invocations are all we received.
Mockito.verify(tool).begin();
Mockito.verify(tool).end();
Mockito.verify(tool).flush();
Mockito.verifyNoMoreInteractions();

另一方面,如果您有任何其他调用发生在您希望验证的序列之外,那么您是正确的,Mockito 目前无法验证这一点。例如,如果您知道必须在 beginflush 之间的某个时刻调用 tool.setPenColor(),但这并不重要如果此调用发生在 end 调用之前或之后,那么您就不走运了。

您可以在其他一些模拟库中处理这种情况。 EasyMock 使这变得最简单 - 例如,对于 begin 首先出现的序列,flush 最后出现,并且我们不关心中间的调用:

DrawTool mock = EasyMock.createMock(DrawTool.class);
EasyMock.checkOrder(mock, true);
mock.begin();
EasyMock.expectLastCall();
EasyMock.checkOrder(mock, false);
mock.end();
EasyMock.expectLastCall();
EasyMock.expect(mock.someOtherCallThatReturnsAValue()).andReturn(null);
EasyMock.checkOrder(mock, true);
mock.flush();
EasyMock.expectLastCall();
EasyMock.replay(mock);

new Drawer().draw(tool);

EasyMock.verify(mock);

在 JMock 2 中似乎可以进行等效测试,尽管不太实用。它是 bit easier在 JMock 1 中,但该库已经过时(大约 JDK 1.3),所以不要使用它。这在 Moxie 中是不可能的(免责声明/无耻插件:我是作者),但现在有一个 todo list item为此。

我无法代表 Mockito 开发人员解释为什么 Mockito 验证 API 文档是这样的 - 最好在邮件列表上询问他们。我确信他们会欢迎补丁。

关于java - 为 Mockito 创建自定义 VerificationMode 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19462130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com