模拟或伪造DbEntityEntry或创建新的DbEntityEntry

时间:2011-02-17 22:13:02

标签: entity-framework ef-code-first

紧接着我的另一个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有什么成功?

或者有更好的方法来处理状态变化吗?

2 个答案:

答案 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>()));