紧接着我的另一个question about mocking DbContext.Set我还有另外一个关于嘲笑EF Code First的问题。
我现在有一个更新的方法,如下所示:
if (entity == null)
throw new ArgumentNullException("entity");
Context.GetIDbSet<T>().Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
Context.CommitChanges();
return entity;
Context是我自己的DbContext的接口。
我遇到的问题是,我该如何处理
Context.Entry(entity).State
。
我已经完成了这段代码,当我有一个真实的DbContext作为我的Context接口的实现时,它就可以工作了。但是当我把假的上下文放在那里时,我不知道如何处理它。
DbEntityEntry类没有构造函数,所以我不能在伪上下文中创建一个新构造函数。
有没有人在CodeFirst解决方案中嘲弄或伪造DbEntityEntry有什么成功?
或者有更好的方法来处理状态变化吗?
答案 0 :(得分:92)
就像其他情况一样,您需要的是添加额外的间接级别:
interface ISalesContext
{
IDbSet<T> GetIDbSet<T>();
void SetModified(object entity)
}
class SalesContext : DbContext, ISalesContext
{
public IDbSet<T> GetIDbSet<T>()
{
return Set<T>();
}
public void SetModified(object entity)
{
Entry(entity).State = EntityState.Modified;
}
}
因此,您只需拨打SetModified
。
答案 1 :(得分:0)
当我需要使用Moq
进行单元测试时,发现了这个问题,不需要您自己的界面。我想将特定字段设置为未修改,但是方法SetModified
也可以与对象一起使用。
DbContext:
public class AppDbContext : DbContext
{
...
public virtual void SetModified(GuidEntityBase entity)
{
Entry(entity).State = EntityState.Modified;
Entry(entity).Property(x => x.CreatedDate).IsModified = false;
Entry(entity).Property(x => x.CreatedBy).IsModified = false;
}
...
}
测试:
var mockContext = new Mock<AppDbContext>();
mockContext.Setup(c => c.MyDbSet).Returns(mockMyDbSet.Object);
mockContext.Setup(c => c.SetModified(It.IsAny<GuidEntityBase>()));