¿Cómo (debería) burlarme de DocumentClient para la prueba de la unidad DocumentDb?
Del nuevo emulador CosmosDb obtuve una especie de repositorio para realizar operaciones básicas de documentdb, este repositorio se inyecta en otras clases. Quería probar la unidad de una consulta básica.
public class DocumentDBRepository<T> where T : class
{
//Details ommited...
public IQueryable<T> GetQueryable()
{
return _client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(_databaseId, _collectionId),
new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true });
}
public async Task<IEnumerable<T>> ExecuteQueryAsync(IQueryable<T> query)
{
IDocumentQuery<T> documentQuery = query.AsDocumentQuery();
List<T> results = new List<T>();
while (documentQuery.HasMoreResults)
{
results.AddRange(await documentQuery.ExecuteNextAsync<T>());
}
return results;
}
}
Este repositorio necesita un cliente de documentos para funcionar, que también se inyecta en el constructor.
public DocumentDBRepository(string databaseId, IDocumentClient client)
{
_client = client;
_databaseId = databaseId;
_collectionId = GetCollectionName();
}
Mi enfoque inicial fue usar el emulador CosmosDb, pero eso requería que el emulador se ejecutara, lo que no me gusta y hace que las pruebas sean más lentas.
Mi segundo enfoque fue tratar de usar un simulacro del cliente de documentos.
var data = new List<MyDocumentClass>
{
new MyDocumentClass{ Description= "BBB" },
new MyDocumentClass{ Description= "ZZZ" },
}
.AsQueryable()
.OrderBy(q => q.Description);
var client = new Mock<IDocumentClient>();
client.As<IDocumentClient>()
.Setup(foo => foo.CreateDocumentQuery<MyDocumentClass>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(data);
DocumentDBRepository<MyDocumentClass> repo= new DocumentDBRepository<MyDocumentClass>(cosmosDatabase, client.Object);
El código que usa este repositorio funciona así:
var query = _documentsRepository.GetQueryable()
.Where(d => d.Description = description)
.OrderByDescending(d => d.description)
.Take(100);
//Execute query async fails.
var result = await _documentsRepository.ExecuteQueryAsync(query);
Falla porque el repositorio intenta convertir elIQueryable
a unIDocumentQuery
objeto, que es muy específico para DocumentDb api (Ver métodoExecuteQueryAsync
encima). Más tarde, se ejecutaHasMoreResults
método sobre el mismo. Entonces el problema es, incluso si me burlo.asDocumentQuery()
para devolver mi objeto, no sé cómo proporcionar un resultado paraHasMoreResults
yExecuteNextAsync
para que tenga sentido para mis pruebas unitarias.
Mi tercera opción sería simular directamente mi repositorio en lugar del objeto DocumentClient. Creo que sería más simple, pero no probaría gran parte de la API de DocumentDb.