ArgumentUsedInMockedClass

ArgumentUsedInMockedClass

我有一个用例,其中我想捕获在方法中传递的值,并且还使用此值定义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
}

09-25 16:46