Я пытаюсь проверить бизнес-логику в запросах в службах. Поэтому я не хочу, чтобы мои тесты имели реальный доступ к базе данных, потому что это модульные тесты, а не интеграционные тесты.Тестирование службы с использованием Entity Framework без инъекции зависимости
Итак, я сделал простой пример моего контекста и как я пытаюсь его подкрепить.
У меня есть юридическое лицо
public class SomeEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
и сервисный
public class Service
{
public int CountSomeEntites()
{
using (var ctx = new Realcontext())
{
int result = ctx.SomeEntities.Count();
return result;
}
}
}
И это реальный контекст
public partial class Realcontext : DbContext
{
public virtual DbSet<SomeEntity> SomeEntities { get; set; }
public Realcontext() : base("name=Realcontext")
{
InitializeContext();
}
partial void InitializeContext();
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
Так что я попытался создать поддельный контекст и я отменил конструктор реального контекста в моем методе тестирования
Это фальшивка контекст
public class FakeContext : DbContext
{
public DbSet<SomeEntity> SomeEntities { get; set; }
public FakeContext()
{
}
}
И, наконец, класс тест
[TestClass]
public class ServiceTests
{
[TestMethod]
public void CountEmployee_ShoulReturnCorrectResult()
{
using (ShimsContext.Create())
{
ShimRealcontext.Constructor = context => GenerateFakeContext();
ShimDbContext.AllInstances.Dispose =() => DummyDispose();
Service service = new Service();
int result = service.CountSomeEntites();
Assert.AreEqual(result, 2);
}
}
private FakeContext GenerateFakeContext()
{
FakeContext fakeContext = new FakeContext();
fakeContext.SomeEntities.AddRange(new[]
{
new SomeEntity {Id = 1, Name = "entity1"},
new SomeEntity {Id = 2, Name = "entity2"}
});
return fakeContext;
}
}
Когда я запустить тест, то RealContext
конструктор возвращается правильно, FakeContext
построен в методе GenerateFakeContext()
, она содержит 2 SomeEntities
и возвращается, но сразу после этого, на службе, свойство SomeEntities
переменной ctx
равно нулю.
Это потому, что моя переменная ctx
объявлена как new RealContext()
? Но вызов конструктора RealContext
возвращает FakeContext()
, так что переменная не должна быть типа FakeContext
?
Я что-то не так? Или есть ли другой способ проверить службу без доступа к реальной базе данных?
В наших тестах мы позаимствовали издевательства из источника EF. Он находится под лицензией Apache. – Eris
Спасибо! Я не знал этого инструмента. Я посмотрю –