'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 |
