如何使用在mockito中调用之间更改状态的相同参数来validation相同模拟方法的调用?

我有以下代码进行unit testing:

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

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

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

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

我创建了以下Answer实现:

 public class CapturingAnswer implements Answer { private final Function capturingFunction; private final List capturedValues = new ArrayList(); public CapturingAnswer(final Function capturingFunction) { super(); this.capturingFunction = capturingFunction; } @Override public T answer(final InvocationOnMock invocation) throws Throwable { capturedValues.add(capturingFunction.apply(invocation)); return null; } public List getCapturedValues() { return Collections.unmodifiableList(capturedValues); } } 

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

 @Test public void testSomething() { CapturingAnswer 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实现完成的捕获,因为这仅在调用被测方法之后使用。

在我原来的评论中,这是我想到的答案。

要嘲笑的课程:

 class MockedClass{ void save(SomeBean sb){ //doStuff } } 

我们需要validationDate对象的类是null。

 class SomeBean{ Date date; Date getDate(){return date;} void setDate(Date date){this.date=date;} } 

被测试的课程:

 class TestClass{ MockedClass mc; TestClass(MockedClass mc){this.mc = mc;} void doWork(){ SomeBean sb = new SomeBean(); mc.save(sb); sb.setDate(new Date()); mc.save(sb); } } 

和测试用例:

 @Test public void testAnswer(){ MockedClass mc = Mockito.mock(MockedClass.class); Mockito.doAnswer(new Answer(){ boolean checkDate = true; @Override public Void answer(InvocationOnMock invocation) throws Throwable { SomeBean sb = (SomeBean) invocation.getArguments()[0]; if(checkDate && sb.getDate() != null){ throw new NullPointerException(); //Or a more meaningful exception } checkDate = false; return null; }}).when(mc).save(Mockito.any(SomeBean.class));; TestClass tc = new TestClass(mc); tc.doWork(); } 

第一次通过这个Answer (我应该在我的原始评论中使用的术语),如果date不为null,这将抛出exception并使测试用例失败。 第二次, checkDate将为false,因此不会执行检查。