Jako dinozaur piszący ręcznie kod uruchamiany na platformie Power Apps („Low-code, you fool!”) stworzyłem sobie dziś klasę repozytorium, umożliwiającą pobieranie metadanych tabel Microsoft Dataverse. Rozwiązanie wydawało mi się być banalnym w swojej prostocie:
public interface IMetadataRepository
{
EntityMetadata GetEntityMedatada(string entityName);
void Initialize(IOrganizationService service);
}
public class MetadataRepository : IMetadataRepository
{
protected IOrganizationService OrganizationService;
public void Initialize(IOrganizationService service)
{
OrganizationService = service;
}
public EntityMetadata GetEntityMedatada(string entityName)
{
var retrieveEntityRequest = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.All,
LogicalName = entityName
};
var response = (RetrieveEntityResponse)OrganizationService.Execute(retrieveEntityRequest);
return response.EntityMetadata;
}
}Powyższe repozytorium wykorzystywałem do dynamicznego pobierania informacji nt. podstawowego atrybutu encji oraz dynamicznego ustawiania jego wartości. Wyglądało to mniej-więcej w następujący sposób:
var entityMetadata = _metadataRepository.GetEntityMedatada(entityName); var entity = new Entity(entityName); entity.Attributes.Add(entityMetadata.PrimaryNameAttribute, entityPrimaryAttributeValue); var entityId = _repository.Create(entity);
Problem pojawił się w momencie próby stworzenia testu jednostkowego dla ww. kodu. Okazało się niestety, że wykorzystywana przeze mnie właściwość klasy EntityMetadata jest tylko do odczytu. Próba utworzenia własnego obiektu ww. typu i poustawiania jego atrybutów wewnątrz testu jednostkowego zakończyła się niepowodzeniem. Na szczęścia ratunkiem okazał się mechanizm refleksji, który do spółki z frameworkiem Moq pozwolił utworzyć „zaślepkę” przedstawionego na początku repozytorium.
Mock<IMetadataRepository> metadataRepository = new Mock<IMetadataRepository>();
metadataRepository.Setup(m => m.GetEntityMedatada(It.IsAny<string>())).Returns(() => {
var metadata = new EntityMetadata();
typeof(EntityMetadata)
.GetProperty("PrimaryNameAttribute")
.SetValue(metadata, "pg_name");
return metadata;
});Nie chcę w tym miejscu wchodzić w dyskusję na temat tego, czy wykorzystania refleksji wewnątrz testów jednostkowych jest dobrą praktyką i czy problem, na który napotkałem nie wynika z błędów w architekturze. Zdaję sobie również sprawę, że powyższą zaślepkę dałoby się pewnie zastąpić dedykowaną strukturą wrapperów. Po rozważeniu alternatyw stwierdziłem jednak, że dla mojego przypadku przytoczone powyżej rozwiązanie jest „good enough”
.
Wykorzystujcie więc na własną odpowiedzialność.

Like
Report
*This post is locked for comments