Я пытаюсь создать абстрактный слой для ObjectContext
. Я понимаю, что OC является Единица работы, но я просто не полностью, как записать хороший интерфейс для него. Идеально я хотел бы смочь выгрузить свой 'RealDataContext', который реализует IDataContext
для чего-то как 'FakeDataContext', который был бы полностью в оперативной памяти.
Причина этого состоит в том, что я хочу смочь протестировать свои репозитории против базы данных в оперативной памяти.
Спасибо!
У вас должна быть возможность создать расширенный класс, производный от ObjectContext и реализующий интерфейс IDataContext. Чтобы действительно иметь возможность имитировать ObjectContext, ваш интерфейс IDataContext должен включать соответствующие подписи (или свойства) для любого члена ObjectContext, который вы используете и хотите имитировать. Что-то вроде следующего должно быть достаточно:
interface IDataContext, IDisposable
{
void AddObject(string entitySetName, object entity);
void Attach(IEntityWithKey entity);
void Detach(object entity);
void DeleteObject(object entity);
int SaveChanges();
int SaveChanges(bool acceptChangesDuringSave);
int SaveChanges(SaveOptions options);
// Any other members you wish to be mockable
}
class DataContext: ObjectContext, IDataContext
{
// nothing here
}
С технической точки зрения, поскольку DataContext наследует все от ObjectContect, реализация IDataContext выполняется ObjectContext. Вам не потребуется дополнительная реализация в классе DataContext. Пока вы всегда вводите (или используете фабрику для создания) экземпляры IDataContext, а не ObjectContext, вы должны иметь возможность имитировать IDataContext при тестировании:
class SomeEntityRepository: IRepository<SomeEntity>
{
public SomeEntityRepository(IDataContext context)
{
m_context = context;
}
private readonly IDataContext m_context;
public SomeEntity GetById(long id)
{
// implementation
}
}
// xUnit.NET & Moq
class SomeEntityRepositoryTests
{
[Fact]
public void GetById_returns_entity_when_valid_id_is_passed()
{
// state and context
var mockContext = new Mock<IDataContext>();
// arrangement
mockContext.Setup(/* configure mock context here */);
var repo = new SomeEntityRepository(mockContext.Object);
// activity
var entity = repo.GetById(100);
// assertions
}
}