我有一个用例,其中我想捕获在方法中传递的值,并且还使用此值定义Mockito行为。
像这样 :
@InjectMocks
private ClassUnderTest classUnderTest;
@Mock
private MockedClass mockedClass;
@Captor
private ArgumentCaptor<ArgumentUsedInMockedClass> captor;
@Test
public void testMethod() {
Result result = new Result();
result.setResultId(RESULT_ID);
Mockito.verify(mockedClass).doSomething(captor.capture());
Mockito.when(mockedClass.doSomething(captor.getValue())).thenReturn(result);
Assert.assertTrue(classUnderTest
.doSomething(foo, bar)
.equals(result));
}
但是我得到这个错误:
[junit] Wanted but not invoked:
[junit] mockedClass.doSomething(
[junit] <Capturing argument>
[junit] );
[junit] Actually, there were zero interactions with this mock.
在我的
doSomething()
函数中,foo和bar用于生成ArgumentUsedInMockedClass
类型的参数。现在,此ArgumentUsedInMockedClass
类型没有正确定义其equals()
,因此,如果我尝试直接使用它,将导致模棱两可的失败即使参数相同,在测试方法中也会生成
Mockito.when(mockedClass.doSomething(argumentUsedInMockedClass)).thenReturn(result);
和argumentUsedInMockedClass
。我试图捕获在此ClassUnderTest中创建的确切对象以定义模仿行为,但在我看来,这就像一个循环,其中第一个Assert.assertTrue(classUnderTest
.doSomething(foo, bar)
.equals(result));
必须实际捕获,但要使其工作,就应该定义
mockedClass
行为,具体取决于它。如何解决这种情况或使用其他测试方法?
最佳答案
之所以会出现错误,是因为您尝试在实际调用该方法之前先验证该方法是否已调用,这在assertTrue
中发生。
您可以这样重写测试:
@Test
public void testMethod() {
Result result = new Result();
result.setResultId(RESULT_ID);
// Define the behavior
Mockito.when(mockedClass.doSomething(any(ArgumentUsedInMockedClass.class)).thenReturn(result);
Assert.assertTrue(classUnderTest
.doSomething(foo, bar)
.equals(result));
Mockito.verify(mockedClass).doSomething(captor.capture());
ArgumentUsedInMockedClass argument = captor.getValue();
// Do some further verification/assertion with argument
}