У меня есть решение, в котором у меня есть проект Data, содержащий файл EF6 .edmx, созданный из существующей базы данных. Я разделил объекты на отдельный проект Entities и имел проект Repositories, который ссылается на них обоих.Как я могу протестировать репозиторий, который использует DbContext с NSubstitute?
Я добавил BaseRepository с некоторыми распространенными методами и хочу его протестировать. В верхней части класса выглядит следующим образом ...
public class BaseRepository<T> : BaseRepositoryInterface<T> where T : class {
private readonly MyEntities _ctx;
private readonly DbSet<T> _dbSet;
public BaseRepository(MyEntities ctx) {
_ctx = ctx;
_dbSet = _ctx.Set<T>();
}
public IEnumerable<T> GetAll() {
return _dbSet;
}
//...
}
После кода я нашел в https://stackoverflow.com/a/21074664/706346, я попробовал следующее ...
[TestMethod]
public void BaseRepository_GetAll() {
IDbSet<Patient> mockDbSet = Substitute.For<IDbSet<Patient>>();
mockDbSet.Provider.Returns(GetPatients().Provider);
mockDbSet.Expression.Returns(GetPatients().Expression);
mockDbSet.ElementType.Returns(GetPatients().ElementType);
mockDbSet.GetEnumerator().Returns(GetPatients().GetEnumerator());
MyEntities mockContext = Substitute.For<MyEntities>();
mockContext.Patients.Returns(mockDbSet);
BaseRepositoryInterface<Patient> patientsRepository
= new BaseRepository<Patient>(mockContext);
List<Patient> patients = patientsRepository.GetAll().ToList();
Assert.AreEqual(GetPatients().Count(), patients.Count);
}
private IQueryable<Patient> GetPatients() {
return new List<Patient> {
new Patient {
ID = 1,
FirstName = "Fred",
Surname = "Ferret"
}
}
.AsQueryable();
}
Обратите внимание, что я изменил файл TT контекста использовать IDbSet, как предложил Стюарт Клемент в своем комментарии от 4 декабря 15:15 в 22:41
Однако, когда я запускаю этот тест, он дает исключение для ссылочной ссылки, поскольку строка в конструкторе базового репозитория, которая устанавливает _dbSet
, оставляет это null ...
_dbSet = _ctx.Set<T>();
Я бы предположил, что мне нужно добавить еще одну строку, когда я настроил свой макет контекста, но я не уверен, что. Я думал, что кода выше должно быть достаточно, чтобы заполнить DbSet.
Любой, кто может объяснить, что я пропустил или сделал неправильно?