模拟或伪造 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> '不包含 Where 的定义