'Mocking DynamoDB mapper query using Mockito

I am trying to mock a very simple line of code that is used to query the DynamoDB using Java. Here is some sample code for the query -

List<Pojo> result;
        try {
            if (filters == null) {
                this.queryExpression = new DynamoDBQueryExpression<Pojo>()
                        .withKeyConditionExpression(partitionKeyCondition)
                        .withExpressionAttributeValues(this.eav);
            } else {
                setFilterQueryExpression(filters);
            }
            result = this.dynamoDBMapper.query(Pojo.class, queryExpression);
        } catch (final Exception e) {
            throw new InternalServerException("Something went wrong with the database query: ", e);
        }

The above piece of code works and I am able to retrieve a List of rows that automatically get deserialized into the Pojo.

I am now trying to Mock the this.dynamoDBMapper.query call as follows -

@Mock
private DynamoDBMapper mapper;
List<Pojo> result = new ArrayList<>();

when(mapper.query(Pojo.class,Mockito.any(DynamoDBQueryExpression.class)).thenReturn(result);

I am unable to do that with error -

Cannot resolve method 'thenReturn(java.util.List<com.amazon.xxx.xxx.Pojo>)'

I also tried another way -

doReturn(result).when(mapper).query(Pojo.class, Mockito.any(DynamoDBQueryExpression.class));

That seems to compile but the test fails with error -

org.mockito.exceptions.misusing.WrongTypeOfReturnValue 

I have looked at other sample where the expected output of the query is of type PaginatedQueryList , I have tried changing to that as well. But I am still not sure why the above throws an error.



Solution 1:[1]

Do you also get the error when you use ArgumentMatchers?

Mockito.when(mapper.query(ArgumentMatchers.any(Pojo.class),ArgumentMatchers.any(DynamoDBQueryExpression.class)).thenReturn(result));

Do you also get the error if you expand the ArgumentMatchers (temporarily)?

Mockito.when(mapper.query(ArgumentMatchers.any(),ArgumentMatchers.any()).thenReturn(result));

Solution 2:[2]

As it turns out, you are missing a parenthesis before .thenReturn in order to complete the when part. Once you add it and switch from return type List to PaginatedQueryList, it should compile. Also note that any is a matcher. Once you specifiy a matcher, all arguments need to be matchers, therefore use eq etc. for your Pojo type. Otherwise, Mockito will show a InvalidUseOfMatchersException during runtime. Here is a simplified example that works for me:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression;
import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MockTest {

    @Test
    void test() {
        DynamoDBMapper mapperMock = mock(DynamoDBMapper.class);
        PaginatedQueryList<String> expected = mock(PaginatedQueryList.class);
        // Note that when needs to be completed before thenReturn can be called.
        when(mapperMock.query(eq(String.class), Mockito.any(DynamoDBQueryExpression.class))).thenReturn(expected);

        QueryService queryService = new QueryService(mapperMock);
        PaginatedQueryList<String> actual = queryService.query();

        assertEquals(expected, actual);
    }

    public class QueryService {
        private final DynamoDBMapper mapper;

        public QueryService(DynamoDBMapper mapper) {
            this.mapper = mapper;
        }

        public PaginatedQueryList<String> query() {
            DynamoDBQueryExpression<String> queryExpression = new DynamoDBQueryExpression<>();
            return mapper.query(String.class, queryExpression);
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dcnis
Solution 2 Bastis Programming Corner