not*_*lkk 5 c# unit-testing entity-framework moq entity-framework-6
我正在使用 EF6。生成的代码类似于:
public partial class MyDataContext : DbContext
{
    public MyDataContext() : base("name=mydata")
    {
    }
    public virtual DbSet<Book> Books { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个通用存储库,如:
public class GenericRepository<TObject> where TObject : class
{
    protected readonly MyDataContext Context;
    protected GenericRepository(MyDataContext context)
    {
        Context = context;
    }
    public virtual DbSet<TObject> GetAll()
    {
        return Context.Set<TObject>();
    }
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个使用 GenericRepository 返回数据的服务:
public class MyDataService<TObject> where TObject : class
{
    private readonly MyDataContext context;
    public MyDataService(MyDataContext ct)
    {
        context = ct;
    }
    public ICollection<TObject> GetAll()
    {
        var r = new GenericRepository<TObject>(context);
        return r.GetAll().ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)
所以我可以得到所有这样的书:
var ds = new MyDataService<Book>(new MyDataContext());
var data = ds.GetAll();
Run Code Online (Sandbox Code Playgroud)
这工作正常。接下来,我尝试使用 Moq 对上述代码进行单元测试,例如:
var books = new List<Book>
{
    new Book {Id = 1, Name = "BBB"},
    new Book {Id = 2, Name = "ZZZ"},
    new Book {Id = 3, Name = "AAA"},
}.AsQueryable();
var mockSet = new Mock<DbSet<Book>>();
mockSet.As<IQueryable<Book>>().Setup(m => m.Provider).Returns(books.Provider);
mockSet.As<IQueryable<Book>>().Setup(m => m.Expression).Returns(books.Expression);
mockSet.As<IQueryable<Book>>().Setup(m => m.ElementType).Returns(books.ElementType);
mockSet.As<IQueryable<Book>>().Setup(m => GetEnumerator()).Returns(books.GetEnumerator());
var mockContext = new Mock<MyDataContext>();
mockContext.Setup(c => c.Books).Returns(mockSet.Object);
var service = new MyDataService<Book>(mockContext.Object);
var data = service.GetAll();
Run Code Online (Sandbox Code Playgroud)
但是,我"Value cannot be null.\r\nParameter name: source"在最后一行收到错误。当我进入代码时,我看到上下文对象中的 Books 集合是空的。
我究竟做错了什么?
那是因为 test 是.Setup(c => c.Books)在数据上下文中设置的,但在方法中的实际代码访问Context.Set<TObject>()中设置GetAll(),因此对于 test 它将最终为null.
尝试更改为
mockContext.Setup(c => c.Set<Book>()).Returns(mockSet.Object);
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           3108 次  |  
        
|   最近记录:  |