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