【问题标题】:Mock Entity Framework For MVC Application Unit testingMVC 应用程序单元测试的模拟实体框架
【发布时间】:2015-03-13 16:41:22
【问题描述】:

我已经使用实体框架[DB] 开发了一个 MVC 应用程序。我已经直接在实体上处理了 CRUD 操作,而不使用 Repository ORM。

现在我打算写单元测试。

是否可以在不使用我的生产数据库的情况下模拟实体?

请建议模拟实体的最佳方法

【问题讨论】:

  • 我写的关于这个主题的这篇博文可能会让你感兴趣:vannevel.net/2015/02/26/11 它使用 Effort 来简单地创建一个内存数据库,其他一切都一样。

标签: asp.net-mvc entity-framework unit-testing mocking


【解决方案1】:

一种可能的方法是将现有的实体框架类包装在一个接口中。例如,您可以创建一个名为IDbContextAdapter 的接口并实现一个名为DbContextAdapter 的类。然后,这将实现接口并简单地将调用中继到真实的DbContext

public interface IDbContextAdapter
{
    IEnumerable<DbEntityValidationResult> GetValidationErrors();
    int SaveChanges();    
    ...
}

然后上课……

public class DbContextAdapter : IDbContextAdapter
{
    private readonly DbContext _realContext;

    public DbContextAdapter(DbContext context)
    {
        _realContext = context;
    }

    public IEnumerable<DbEntityValidationResult> GetValidationErrors()
    {
        return _realContext.GetValidationErrors();
    }

    public int SaveChanges()
    {
        _realContext.SaveChanges();
    }
}

现在您可以在整个代码中使用IDbContextAdapter,并且可以在测试期间模拟接口。您可以为每个进行外部调用的实体框架类执行此操作,并且它还允许您在使用 DbContext 方法时添加额外的错误检查等。

我已经在 Azure 表/队列存储中使用了这种方法,它运行良好,但需要额外编码才能包装真实对象。

更新 #1:作为旁注,我不会包装所有 EF 对象。相反,只是那些访问外部资源的人。因此,如果我的方法有一个类型为 EF 对象的参数,并且该对象仅具有一些属性,则将其包含在您的 IDbContextAdapter 方法签名中,并且不要费心包装它(这也适用于返回值)。

更新 #2:更新了代码示例以说明更新 #1 中的要点。请注意 GetValidationErrors 方法如何不费心包装 EF 类型 DbEntityValidationResult,而是简单地返回从真正的 DbContext 返回的实际对象。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多