[C#.NET][Entity Framework] 單元測試 - 使用 NSubstitute 測試 EF6
此篇是研究性質,不建議 Mock EF
打從 EF6 開始,就可以使用 Mock Framework 來進行 DbSet 測試,下篇是使用 moq
https://msdn.microsoft.com/en-us/data/dn314429.aspx
我想把它換成 NSubstitute
我需要模擬兩各物件,DbContext、DbSet,比較麻煩的是DbSet,需要模擬四個方法
- Provider
- Expression
- ElementType
- GetEnumerator()
Mock DbSet:
var data = new List<Employee>()
{
new Employee() { EmployeeID = 1, LastName = "余", FirstName = "小章" },
new Employee() { EmployeeID = 2, LastName = "王", FirstName = "小華" },
new Employee() { EmployeeID = 3, LastName = "蔡", FirstName = "比巴" },
}.AsQueryable();
var mockDbSet = Substitute.For<IDbSet<Employee>, DbSet<Employee>>();
mockDbSet.Provider.Returns(data.Provider);
mockDbSet.Expression.Returns(data.Expression);
mockDbSet.ElementType.Returns(data.ElementType);
mockDbSet.GetEnumerator().Returns(data.GetEnumerator());
Mock DbContext:
var mockDbContext = Substitute.For<NorthwindDbContext>();
mockDbContext.Employees.Returns(mockDbSet);
把這4個成員用擴充方法包起來
public static class ExtentionMethods
{
public static IDbSet<T> Initialize<T>(this IDbSet<T> dbSet, IQueryable<T> data) where T : class
{
dbSet.Provider.Returns(data.Provider);
dbSet.Expression.Returns(data.Expression);
dbSet.ElementType.Returns(data.ElementType);
dbSet.GetEnumerator().Returns(data.GetEnumerator());
return dbSet;
}
}
完整程式碼:
[TestMethod]
public void Mock_DbContext()
{
//arrange
var data = new List<Employee>()
{
new Employee() { EmployeeID = 1, LastName = "余", FirstName = "小章" },
new Employee() { EmployeeID = 2, LastName = "王", FirstName = "小華" },
new Employee() { EmployeeID = 3, LastName = "蔡", FirstName = "比巴" },
}.AsQueryable();
//var mockDbSet = Substitute.For<IDbSet<Employee>, DbSet<Employee>>();
//mockDbSet.Provider.Returns(data.Provider);
//mockDbSet.Expression.Returns(data.Expression);
//mockDbSet.ElementType.Returns(data.ElementType);
//mockDbSet.GetEnumerator().Returns(data.GetEnumerator());
var mockDbSet = Substitute.For<IDbSet<Employee>, DbSet<Employee>>().Initialize(data);
var mockDbContext = Substitute.For<NorthwindDbContext>();
mockDbContext.Employees.Returns(mockDbSet);
//act
var query = mockDbContext.Employees.FirstOrDefault(p => p.EmployeeID == 2);
//assert
Assert.AreEqual("小華", query.FirstName);
}
NSubstistute 越看越順眼
文章出自:https://www.dotblogs.com.tw/yc421206/2015/02/16/149502
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET