0

我正在尝试模拟外部调用以及 ArgumentMatcher 以将输入值与请求匹配。但是当我试图从 ArgumentMatcher 对象中获取地图时,它给了我一个空值。

Mockito.when(
                dynamoDbMapper.scanPage(eq(ABC.class), argThat(new ArgumentMatcher<DynamoDBScanExpression>() {

                    @Override
                    public boolean matches(Object argument)
                    {
                        DynamoDBScanExpression scanExp = (DynamoDBScanExpression) argument;
                        Assert.assertEquals("5", scanExp.getLimit());
                        Assert.assertEquals("xyz",scanExp.getFilterExpression());
                        Assert.assertEquals(new HashMap(), scanExp.getExpressionAttributeNames());

                            return true;
                    }

                }))).thenReturn(prepareScanResponse());

这个表达式 scanExp.getExpressionAttributeNames() 理想情况下应该返回一个地图,但给我一个空值。

所以假设我必须模拟一个输入包含地图的请求,然后尝试在包含地图作为属性的那个 inout 对象上实现 ArgumentMatcher,我该怎么做?

4

1 回答 1

1

为什么不使用@Captor? Captors 用于获取传递给方法的记录参数。这似乎比尝试滥用匹配器更干净。

@ExtendWith(MockitoExtension.class)
class MarketplaceHttpConnectorImplTest {
    @Captor
    ArgumentCaptor<DynamoDBScanExpression> scanExpressionCaptor;

    @Mock
    DynamoMapper dynamoDbMapper; // or something like this

    @InjectMocks
    MyClassToTest sut; // System Under Test

    @Test
    public void myTest() {
        // prepare mocks
        when(dynamoDbMapper.scanPage(eq(ABC.class), any(DynamoDBScanExpression.class)).thenReturn(prepareScanResponse());

        // Now call the method to test
        sut.methodToCall();

        // Verify calls
        verify(dynamoDbMapper, times(1)).scanPage(eq(ABC.class), scanExpressionCaptor.capture());
        DynamoDBScanExpression param = scanExpressionCaptor.getValue();

        // now test what was passed to the method.
        assertNotNull(param);
        // .....
    }
}

顺便说一句:不要介意 JUnit5。它也适用于 JUnit4。另外,我认为只有一个值。您可以同时捕获多个值@Captor并检查所有值。

于 2019-04-01T14:34:17.453 回答