I have the following simple DynamoDBDao that contains one method that queries an index and returns a map of results.
import com.amazonaws.services.dynamodbv2.document.*; public class DynamoDBDao implements Dao{ private Table table; private Index regionIndex; public DynamoDBDao(Table table) { this.table = table; } @PostConstruct void initialize(){ this.regionIndex = table.getIndex(GSI_REGION_INDEX); } @Override public Map<String, Long> read(String region) { ItemCollection<QueryOutcome> items = regionIndex.query(ATTR_REGION, region); Map<String, Long> results = new HashMap<>(); for (Item item : items) { String key = item.getString(PRIMARY_KEY); long value = item.getLong(ATTR_VALUE); results.put(key, value); } return results; } }
I am trying to write a unit test that checks that when the DynamoDB index returns an ItemCollection, then Tao returns the corresponding result map.
public class DynamoDBDaoTest { private String key1 = "key1"; private String key2 = "key2"; private String key3 = "key3"; private Long value1 = 1l; private Long value2 = 2l; private Long value3 = 3l; @InjectMocks private DynamoDBDao dynamoDBDao; @Mock private Table table; @Mock private Index regionIndex; @Mock ItemCollection<QueryOutcome> items; @Mock Iterator iterator; @Mock private Item item1; @Mock private Item item2; @Mock private Item item3; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(table.getIndex(DaoDynamo.GSI_REGION_INDEX)).thenReturn(regionIndex); dynamoDBDao.initialize(); when(item1.getString(anyString())).thenReturn(key1); when(item1.getLong(anyString())).thenReturn(value1); when(item2.getString(anyString())).thenReturn(key2); when(item2.getLong(anyString())).thenReturn(value2); when(item3.getString(anyString())).thenReturn(key3); when(item3.getLong(anyString())).thenReturn(value3); } @Test public void shouldReturnResultsMapWhenQueryReturnsItemCollection(){ when(regionIndex.query(anyString(), anyString())).thenReturn(items); when(items.iterator()).thenReturn(iterator); when(iterator.hasNext()) .thenReturn(true) .thenReturn(true) .thenReturn(true) .thenReturn(false); when(iterator.next()) .thenReturn(item1) .thenReturn(item2) .thenReturn(item3); Map<String, Long> results = soaDynamoDbDao.readAll("region"); assertThat(results.size(), is(3)); assertThat(results.get(key1), is(value1)); assertThat(results.get(key2), is(value2)); assertThat(results.get(key3), is(value3)); } }
My problem is that items.iterator () does not actually return Iterator, it returns IteratorSupport, which is a private package class in the DynamoDB document API. This means that I cannot actually make fun of it, as I did above, and therefore I cannot complete the rest of my test.
What can I do in this case? How do I unit test my DAO correctly give this terrible batch class in the DynamoDB document API?
source share