I have a query statement which returns a PaginatedQueryList
and I assign it to a List. Then I operate on the list.
List<MyClass> entries= mapper.query(MyClass.class, queryExpression);
//Logic to test
Map<String, Map> map = entries.stream()
.collect(Collectors.toMap(MyClass::getA, MyClass::getB));
....
....
I tried to test it like
when(mapper.query(eq(MyClass.class), any(DynamoDBQueryExpression.class)))
.thenReturn((PaginatedQueryList<MyClass>) list);
where list
is List<MyClass>
(ArrayList) that I construct myself and want to pass it to the main program to test the main logic.
But it throws
java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList
How can I send the list when it executes mappper.query(..)
.
The motive is to send the list that I constructed to entries
when executing mapper.query(..)
.
NOTE:
I also tried sending a mocked
PaginatedQueryList but when it does entries.stream()
I want to send the actual stream.
I tried like
when(paginatedQueryList.stream()).thenReturn(Stream.of(list.get(0), list.get(1)));
It throws
java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
NOTE 2:
I use entries.stream()
twice in my logic to test
Class PaginatedQueryList<T>Paginated results are loaded on demand when the user executes an operation that requires them. Some operations, such as size(), must fetch the entire list, but results are lazily fetched page by page when possible.
The DynamoDBMapper class is the entry point to Amazon DynamoDB. It provides access to a DynamoDB endpoint and enables you to access your data in various tables. It also enables you to perform various create, read, update, and delete (CRUD) operations on items, and run queries and scans against tables.
Mockito has some powerful tools for this.
List<MyClass> list = new ArrayList<>();
when(mapper.query(eq(MyClass.class), any(DynamoDBQueryExpression.class)))
.thenReturn(mock(PaginatedQueryList.class, withSettings().defaultAnswer(new ForwardsInvocations(list))));
This will return a mocked PaginatedQueryList
which forwards all method calls to list
.
I was able to solve the problem by sending mocked PaginatedQueryList
and then send list.stream()
twice (for each access of entries.stream()
).
when(paginatedQueryList.stream()).thenReturn(list.stream()).thenReturn(list.stream());
Any better approaches are welcome.
My answer is a generic solution for mocking PaginatedQueryList in tests (might be useful for googlers, since there's not much answers for this topic).
For my test this worked:
// given
List<UserDevice> expectedDevices = Arrays.asList(generateUserDevice(USER_ID, DEVICE_ID), generateUserDevice(USER_ID, "deviceId2"));
PaginatedQueryList listMock = mock(PaginatedQueryList.class);
when(listMock.listIterator()).thenReturn(expectedDevices.listIterator());
when(mapper.query(eq(UserDevice.class), any(DynamoDBQueryExpression.class))).thenReturn(listMock);
// when
List<UserDevice> devices = dao.findAll(USER_ID);
// then
assertEquals(expectedDevices, devices);
so, as you can see, I mocked the PaginatedQueryList and mocked its listIterator() method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With