我使用EF6。生成的代码是一样的东西:Moq - 用DbEntityEntry更新
public partial class MyDataContext : DbContext
{
public MyDataContext() : base("name=mydata")
{
}
public virtual DbSet<Book> Books { get; set; }
}
然后,我有一个通用的存储库,如:
public class GenericRepository<TObject> where TObject : class
{
protected readonly MyDataContext Context;
protected GenericRepository(MyDataContext context)
{
Context = context;
}
public virtual TObject Update(TObject data, int id)
{
if (data == null)
return null;
TObject obj = Context.Set<TObject>().Find(id);
if (obj != null)
{
Context.Entry(obj).CurrentValues.SetValues(data);
Context.SaveChanges();
}
return obj;
}
}
然后,我有一个使用GenericRepository更新数据的服务:
public class MyDataService<TObject> where TObject : class
{
private readonly MyDataContext context;
public MyDataService(MyDataContext ct)
{
context = ct;
}
public TObject Update(TObject obj, int id)
{
var r = new GenericRepository<TObject>(context);
return r.Update(obj, id);
}
}
所以我可以用这样的东西来更新书籍:
var ds = new MyDataService<Book>(new MyDataContext());
var data = ds.Update(new Book { Name = "New Name" }, 1);
这工作正常。接下来,我尝试使用起订量来的单元测试上面的代码的东西,如:
var updatedBook = new Book { Name = "Update Book Name" };
var mockSet = new Mock<DbSet<Book>>();
var mockContext = new Mock<MyDataContext>();
mockContext.Setup(c => c.Books).Returns(mockSet.Object);
mockContext.Setup(c => c.Set<Book>().Find(It.IsAny<object[]>()))
.Returns<object[]>(ids => chips.FirstOrDefault(d => d.Id == (int)ids[0]));
var service = new MyDataService<Book>(mockContext.Object);
var data = service.Update(updatedBook, 1);
但是,我上Context.Entry(obj).CurrentValues.SetValues(data)
线异常。
如何正确模拟Update方法?
抽象所有的东西。 :),但严重的是,你的课程应该依赖于抽象而不是结核。那说。所有上面的类都应该在接口后面抽象出来。并且您还将不同的图层紧密结合。服务层不需要知道数据上下文 – Nkosi