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

Posted

技术标签:

【中文标题】模拟或伪造 DbEntityEntry 或创建新的 DbEntityEntry【英文标题】:Mocking or faking DbEntityEntry or creating a new DbEntityEntry 【发布时间】:2011-06-29 10:49:15 【问题描述】:

继我的另一个 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 取得任何成功?

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

【问题讨论】:

【参考方案1】:

当我需要用Moq 进行单元测试时发现了这个问题,不需要你自己的界面。我想将特定字段设置为不修改,但 SetModified 方法也可以与对象一起使用。

数据库上下文:

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

【讨论】:

【参考方案2】:

就像其他情况一样,您需要添加一个额外的间接级别:

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,而不是调用实现。

【讨论】:

谢谢...当我不需要时,我一直在思考“如何模拟条目”,我只需要模拟修改后的功能...我几乎很尴尬,它是如此明显现在。 别这样 - 作为开发人员,我们的生活充满了“呃!”时刻:-) +9000 我刚刚花了一个小时研究如何使用内部 ctor 和内部类来模拟类。我动不动就被挫败,解决方案很简单!感谢提问者和回答者 @DiegoMijelshon 这很优雅! @ErwinRooijakkers 响应较晚,但在您的测试中,您什么也没做。只需在 ISalesContext 的假冒中实现 SetModified 并将其留空。只需public void SetModified(object entity)

以上是关于模拟或伪造 DbEntityEntry 或创建新的 DbEntityEntry的主要内容,如果未能解决你的问题,请参考以下文章

DBEntityEntry类

实体框架 DbEntityEntry> '不包含 Where 的定义

Android模拟器没有启动?

模拟登录博客园

将测试替身与 DbEntityEntry 和 DbPropertyEntry 一起使用

尝试在模拟器或设备上构建 React Native 项目时出现 Xcode 错误