Mam następujące proste DynamoDBDao, które zawiera jedną metodę, która zapytuje indeks i zwraca mapę wyników.Mockito: Wyśmiewanie prywatnych klas pakietów
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;
}
}
Próbuję napisać badanej jednostki, która sprawdza, gdy indeks DynamoDB zwraca ItemCollection wtedy Dao zwraca wyniki odpowiednią 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));
}
}
Moim problemem jest to, że items.iterator() faktycznie nie powrócić Iterator zwróci IteratorSupport który jest pakiet prywatne klasa w dokumencie DynamoDB API. Oznacza to, że nie mogę tak naprawdę kpić z tego, co zrobiłem powyżej, więc nie mogę dokończyć reszty mojego testu.
Co mogę zrobić w tym przypadku? W jaki sposób mogę przetestować jednostkę DAO poprawnie, biorąc pod uwagę tę okropną klasę prywatną pakietu w interfejsie API DynamoDB?
szczegóły implementacji jak widoczności są jednym z powodów, dla wytycznej „[Nie makiety typy nie są właścicielami] (http : //www.davesquared.net/2011/04/dont-mock-types-you-dont-own.html) ". Czy możesz napisać streszczenie do dowolnego z tych obiektów za pomocą kontraktu/implementacji, którą kontrolujesz, lub zamiast tego kodować interfejs? –
Cześć Jeff, dziękuję za komentarz. Nie widzę sposobu, w jaki mogę napisać abstrakcję dla tych obiektów za pomocą kontraktu/implementacji, którą kontroluję. Wykorzystałem obecny zestaw narzędzi, który jest ograniczony moją wiedzą i doświadczeniem. Czy widzisz coś, czego obecnie nie mogę? Jeśli tak, byłbym wdzięczny, gdybyś wskazał mi właściwy kierunek. –