我試圖在服務中的查詢中測試業務邏輯。所以我不希望我的測試能夠真正訪問數據庫,因爲它們是單元測試,而不是集成測試。使用實體框架而不依賴注入的測試服務
所以我已經做了一個簡單的例子,我的上下文,以及我如何試圖填補它。
我有一個實體
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
並返回,但在服務之後,變量ctx
的屬性SomeEntities
等於空。
是因爲我的變量ctx
被聲明爲new RealContext()
?但調用RealContext
的構造函數會返回FakeContext()
,那麼該變量應該是FakeContext
類型的變量嗎?
我做錯了什麼?還是有沒有其他的方式來測試服務而不訪問真正的數據庫?
在我們的測試中,我們借鑑了EF測試源中的模擬。它在Apache許可證下。 – Eris
謝謝!我不知道這個工具。我會看看 –