gpt4 book ai didi

java - Mockito verify + any 行为不可预测

转载 作者:行者123 更新时间:2023-11-28 20:20:21 24 4
gpt4 key购买 nike

我正在为 Spring MVC + axon 中的 Controller 编写集成测试。

我的 Controller 是一个简单的 RestController,有一个方法:

@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void createEventProposal(@RequestBody CreateEventProposalForm form) {
CreateEventProposalCommand command = new CreateEventProposalCommand(
new EventProposalId(),
form.getName(),
EventDescription.of(form.getDescription()),
form.getMinimalInterestThreshold());

commandGateway.send(command);
}

CreateEventProposalForm 只是一个值类,用于从传入的 json 中收集所有参数。

EventProposalId

是另一个值对象,代表一个标识符。它可以基于字符串构建,也可以不带任何参数——在后一种情况下,会生成一个 UUID。

现在,我想编写一个测试用例,给定一个正确的 json,我的 Controller 应该使用正确的命令对象在我的命令网关模拟上调用发送方法。

这就是 mockito 行为有点不可预测的时候:

@Test
public void givenPostRequestShouldSendAppropriateCommandViaCommandHandler() throws Exception {

final String jsonString = asJsonString(
new CreateEventProposalForm(eventProposalName, eventDescription, minimalInterestThreshold)
);

mockMvc.perform(
post(URL_PATH)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonString)
);

verify(commandGatewayMock, times(1))
.send(
new CreateEventProposalCommand(
any(EventProposalId.class),
eventProposalName,
EventDescription.of(eventDescription),
minimalInterestThreshold
)
);


}

如果我将 EventProposalId 的新实例传递给 EventProposalCommand 构造函数,请说:

new CreateEventProposalCommand(
EventProposalId.of("anId"),
eventProposalName,
EventDescription.of(eventDescription),
minimalInterestThreshold
)

如您所料,它失败了。但是给 any(EventProposalId.class) 相反,我可以传递完全虚拟的值,比如

new CreateEventProposalCommand(
any(EventProposalId.class),
"dummy name",
EventDescription.of("dummy description"),
666
)

与其他参数一样,测试总是通过。

如果没有方法参数拦截,我怎么能做出这样的断言呢?这是 mockito 的 bug 还是应该这样?

最佳答案

展开Paweł's correct answer ,它通过了,因为您在模拟上匹配单参数方法时巧合使用了一个匹配器,这就是行为不一致的原因。

当你写的时候:

verify(commandGatewayMock, times(1))
.send(
new CreateEventProposalCommand(
any(EventProposalId.class),
eventProposalName,
EventDescription.of(eventDescription),
minimalInterestThreshold
)
);

...Mockito 实际上匹配为:

verify(commandGatewayMock, times(1))
.send(any());

Mockito matchers like any work via side-effects.any 的调用不会返回匹配任何对象的特殊对象实例;相反,它返回 null 并告诉 Mockito 跳过匹配某个参数。如果您在 stub 或验证中使用任何匹配器,这就是您通常需要对所有参数使用匹配器的部分原因:匹配器和参数必须一对一排列,而 Mockito 不够智能,无法深入使用匹配器(即在对 new CreateEventProposalCommand 的调用中)。

在这种情况下,Mockito 在堆栈上看到一个 any 匹配器(any(EventProposalId.class)any 上的参数只是帮助 javac 找出泛型)和单参数方法的验证(commandGatewayMock.send),并错误地假设两者一起出现——这会导致您的测试通过而不管参数如何到您的 CreateEventProposalCommand 构造函数。

关于java - Mockito verify + any 行为不可预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28052493/

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