問題描述
我有以下代碼要進行單元測試:
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.
這篇關于如何使用相同的參數驗證對同一模擬方法的調用,該參數在模擬中的調用之間改變狀態?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!