有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将ArgumentCaptor与Mockito一起使用。when()。然后返回()

我有一个用例,在这个用例中,我希望捕获在方法中传递的值,并使用这个值来定义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.

在mydoSomething()函数中,foo和bar用于生成类型为ArgumentUsedInMockedClass的参数。现在,这个ArgumentUsedInMockedClass类型没有正确定义它的equals(),因此如果我试图直接使用

Mockito.when(mockedClass.doSomething(argumentUsedInMockedClass)).thenReturn(result);,在测试方法中生成argumentUsedInMockedClass,即使其参数相同。我试图捕获在这个ClassUnderTest中创建的确切对象来定义mockito行为,但在我看来,这就像一个循环,首先

Assert.assertTrue(classUnderTest
            .doSomething(foo, bar)
            .equals(result));

必须发生实际捕获,但要使其工作mockedClass行为应该定义,这取决于它

我如何避开这种情况或使用其他测试方法


共 (1) 个答案

  1. # 1 楼答案

    之所以会出现错误,是因为您试图在实际调用该方法之前验证该方法是否已被调用,这种情况发生在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
    }