問題描述
我有以下代碼要進(jìn)行單元測(cè)試:
I have the following code to be unit tested:
public void foo() {
Entity entity = //...
persistence.save(entity);
entity.setDate(new Date());
persistence.save(entity);
}
我想驗(yàn)證在第一次調(diào)用 persistence.save
entity.getDate()
時(shí)返回 null
.
I would like to verify that on the first invocation of persistence.save
entity.getDate()
returns null
.
因此我無法使用 Mockito.verify(/*...*/)
因?yàn)楫?dāng)時(shí)方法 foo
已經(jīng)完成并且 entity.setDate(Date)
被調(diào)用.
Therefore I'm unable to use Mockito.verify(/*...*/)
because at that time the method foo
already completed and entity.setDate(Date)
was called.
所以我認(rèn)為我需要在調(diào)用發(fā)生時(shí)對(duì)調(diào)用進(jìn)行驗(yàn)證.如何使用 Mockito 做到這一點(diǎn)?
So I think I need to do verifications of invocations already at the time the invocations happen. How do I do this using Mockito?
推薦答案
我創(chuàng)建了以下 Answer
實(shí)現(xiàn):
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);
}
}
此答案捕獲正在執(zhí)行的調(diào)用的屬性.capturedValues
然后可以用于簡單的斷言.該實(shí)現(xiàn)使用 Java 8 API.如果這不可用,則需要使用能夠?qū)?InvocationOnMock
轉(zhuǎn)換為捕獲值的接口.測(cè)試用例中的用法是這樣的:
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
無法實(shí)現(xiàn)由呈現(xiàn)的 Answer
實(shí)現(xiàn)完成的捕獲,因?yàn)檫@僅在調(diào)用被測(cè)方法后使用.
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.
這篇關(guān)于如何使用相同的參數(shù)驗(yàn)證對(duì)同一模擬方法的調(diào)用,該參數(shù)在模擬中的調(diào)用之間改變狀態(tài)?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!