Ho il seguente semplice DynamoDBDao che contiene un metodo che richiede un indice e restituisce una mappa dei risultati.Mockito: classi private pacchetto di simulazione
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;
}
}
sto cercando di scrivere uno unit test che verifica che quando l'indice DynamoDB restituisce un ItemCollection poi il Tao restituisce i risultati mappa corrispondente.
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));
}
}
mio problema è che items.iterator() in realtà non tornare Iterator restituisce un IteratorSupport che è una classe privata pacchetto nel documento API DynamoDB. Ciò significa che non posso realmente deriderlo come ho fatto sopra e quindi non posso completare il resto del mio test.
Cosa posso fare in questo caso? Come faccio a testare unitamente il mio DAO dato questo terribile pacchetto di classe privata nell'API del documento DynamoDB?
modalità d'attuazione, come la visibilità sono uno dei motivi per la linea guida "[Non finta tipi non ti appartengono] (http : //www.davesquared.net/2011/04/dont-mock-types-you-dont-own.html)". Puoi scrivere un'astrazione su uno di questi oggetti con un contratto/un'implementazione che controlli o un codice su un'interfaccia? –
Ciao Jeff, grazie per il tuo commento. Non vedo come posso scrivere un'astrazione attraverso questi oggetti con un contratto/implementazione che controllo. Ho esaurito il mio attuale set di strumenti che è limitato dalla mia conoscenza ed esperienza. Riesci a vedere qualcosa che al momento non posso? Se è così, ti sarei grato se potessi indicarmi la giusta direzione. –