[C#.NET][Entity Framework] 單元測試 - 使用 NSubstitute 測試 EF6

[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,需要模擬四個方法

  1. Provider
  2. Expression
  3. ElementType
  4. 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;
    }
} 

 

完整程式碼:

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.RadGridPaging/UnitTestProject1/UnitTest1.cs

[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

Image result for microsoft+mvp+logo