У меня проблема с настройкой макета (используя moq).
У нас есть общий репозиторий:
public class Repository<T> : IRepository<T>
where T : EntityBase
{
public Repository(DbSet<T> set)
{
Set = set;
}
[...]
}
И я хотел бы динамически создавать репозитории, которые будут возвращены нашим IRepositoryResolver:
public interface IRepositoryResolver
{
TRepository Resolve<TRepository, TEntity>()
where TRepository : IRepository<TEntity>
where TEntity : EntityBase;
IRepository<TEntity> ResolveFor<TEntity>()
where TEntity : EntityBase;
IRepository<TEntity> ResolveFor<TEntity>(TEntity entity)
where TEntity : EntityBase;
}
Для этого я реализовал следующие методы установки имитации:
private void SetupRepositoryResolverMock()
{
var basisDataTypes = Assembly.GetAssembly(typeof(Basisdata))
.GetTypes()
.Where(p => p.IsClass && !p.IsAbstract
&& typeof(Basisdata).IsAssignableFrom(p))
.ToList();
Basisdata[] basisdataInstances = new Basisdata[basisDataTypes.Count];
for (int i = 0; i < basisDataTypes.Count; i++)
{
basisdataInstances[i] = (Basisdata)Activator.CreateInstance(basisDataTypes.ElementAt(i));
}
_repositoryResolverMock = new Mock<IRepositoryResolver>();
foreach (var basisdataInstance in basisdataInstances)
{
Type genericRepository = typeof(Repository<>);
Type constructedRepository = genericRepository.MakeGenericType(basisdataInstance.GetType());
var repositoryInstance = Activator.CreateInstance(constructedRepository, GetQueryableMockDbSet(new[] { basisdataInstance }).Object);
//_repositoryResolverMock
// .Setup(x => x.ResolveFor(basisdataInstance))
// .Returns(() => repositoryInstance);
}
}
private static Mock<DbSet<T>> GetQueryableMockDbSet<T>(ICollection<T> sourceList) where T : EntityBase
{
[...]
}
Модель данных: конкретные реализации расширяют абстрактные базисные данные, которые расширяют абстрактные EntityBase
Теперь моя проблема в том, что переданный тип GetQueryableMockDbSet всегда будет возвращать экземпляр Mock<DbSet<Basisdata>>
вместо DbSet конкретной реализации в строке var repositoryInstance = Activator.CreateInstance(constructedRepository, GetQueryableMockDbSet(new[] { basisdataInstance }).Object);
, что, очевидно, приводит к исключению, поскольку T
не соответствует для хранилища. и DBSet.
Вопрос: Как заставить GetQueryableMockDbSet возвращать набор DB для правильного типа?
Обратите внимание, что я хочу, чтобы это было динамически, и я не знаю всех сущностей, расширяющих Базисданные.
[Edit] здесь методы тестирования и настройки:
[SetUp]
public void Setup()
{
SetupServiceMock();
SetupRepositoryResolverMock();
SetupPersonalModuleMock();
_onlineSyncServicePersonal = new OnlineSyncServicePersonal(_serviceMock.Object, _repositoryResolverMock.Object, new[] { _personalModuleMock.Object });
}
[Test]
public void CheckoutTest()
{
// arrange
var checkoutRequest = new CheckoutRequest
{
DienstId = Guid.NewGuid(),
OrganisationId = Guid.NewGuid(),
CheckoutId = Guid.NewGuid(),
LockModuleNames = new[]
{
Constants.ModuleName.BASE,
Constants.ModuleName.PERSONAL
}
};
// act
var checkoutResult = _onlineSyncServicePersonal.Checkout(checkoutRequest);
// assert
}