如何使用相同的参数验证对同一模拟方法的调用,该参数在模拟中的调用之间改变状态?

How to verify invocations of the same mock method with the same argument that changes state between invocations in mockito?(如何使用相同的参数验证对同一模拟方法的调用,该参数在模拟中的调用之间改变状态?)
本文介绍了如何使用相同的参数验证对同一模拟方法的调用,该参数在模拟中的调用之间改变状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我有以下代码要进行单元测试:

I have the following code to be unit tested:

public void foo() {
    Entity entity = //...
    persistence.save(entity);
    entity.setDate(new Date());
    persistence.save(entity);
}

我想验证在第一次调用 persistence.save entity.getDate() 时返回 null.

I would like to verify that on the first invocation of persistence.save entity.getDate() returns null.

因此我无法使用 Mockito.verify(/*...*/) 因为当时方法 foo 已经完成并且 entity.setDate(Date) 被调用.

Therefore I'm unable to use Mockito.verify(/*...*/) because at that time the method foo already completed and entity.setDate(Date) was called.

所以我认为我需要在调用发生时对调用进行验证.如何使用 Mockito 做到这一点?

So I think I need to do verifications of invocations already at the time the invocations happen. How do I do this using Mockito?

推荐答案

我创建了以下 Answer 实现:

I created the following Answer implementation:

public class CapturingAnswer<T, R> implements Answer<T> {

    private final Function<InvocationOnMock, R> capturingFunction;

    private final List<R> capturedValues = new ArrayList<R>();

    public CapturingAnswer(final Function<InvocationOnMock, R> capturingFunction) {
        super();
        this.capturingFunction = capturingFunction;
    }

    @Override
    public T answer(final InvocationOnMock invocation) throws Throwable {
        capturedValues.add(capturingFunction.apply(invocation));
        return null;
    }

    public List<R> getCapturedValues() {
        return Collections.unmodifiableList(capturedValues);
    }

}

此答案捕获正在执行的调用的属性.capturedValues 然后可以用于简单的断言.该实现使用 Java 8 API.如果这不可用,则需要使用能够将 InvocationOnMock 转换为捕获值的接口.测试用例中的用法是这样的:

This answer captures properties of the invocations being made. The capturedValues can then be used for simple assertions. The implementation uses Java 8 API. If that is not available one would need to use an interface that is able to convert the InvocationOnMock to the captured value. The usage in the testcase is like this:

@Test
public void testSomething() {
    CapturingAnswer<Void,Date> captureDates = new CapturingAnswer<>(this::getEntityDate)
    Mockito.doAnswer(captureDates).when(persistence).save(Mockito.any(Entity.class));

    service.foo();

    Assert.assertNull(captureDates.getCapturedValues().get(0));
}

private Date getEntityDate(InvocationOnMock invocation) {
    Entity entity = (Entity)invocation.getArguments()[0];
    return entity.getDate();
}

使用 Mockitos ArgumentCaptor 无法实现由呈现的 Answer 实现完成的捕获,因为这仅在调用被测方法后使用.

The capturing that is done by the presented Answer implementation can't be achieved with Mockitos ArgumentCaptor because this is only used after the invocation of the method under test.

这篇关于如何使用相同的参数验证对同一模拟方法的调用,该参数在模拟中的调用之间改变状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Sending a keyboard event from java to any application (on-screen-keyboard)(将键盘事件从 java 发送到任何应用程序(屏幕键盘))
How to make JComboBox selected item not changed when scrolling through its popuplist using keyboard(使用键盘滚动其弹出列表时如何使 JComboBox 所选项目不更改)
Capturing keystrokes without focus(在没有焦点的情况下捕获击键)
How can I position a layout right above the android on-screen keyboard?(如何将布局放置在 android 屏幕键盘的正上方?)
How to check for key being held down on startup in Java(如何检查在Java中启动时按住的键)
Android - Get keyboard key press(Android - 获取键盘按键)