如何使用IdentityDbContext模拟实体框架?

时间:2017-09-18 08:33:27

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

我正在开发一个带有个人身份验证的ASP.NET MVC Web应用程序,用于存储有关用户汽车的详细信息。我将需要通过模拟实体框架对Web应用程序进行单元测试,因此我已经阅读了我将需要为ApplicationDbContext类实现一个接口。

这是我第一次尝试使用实体框架,我只想检查我的ApplicationDbContext类和接口是否适合在单元测试时模拟框架?

public interface IApplicationDbContext : IDisposable
{
    IDbSet<ApplicationUser> Users { get; set; }
    DbSet<CarModel> Cars { get; set; }
    int SaveChanges();
    void MarkAsModified(CarModel car);
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
{
    public ApplicationDbContext()
        : base("ApplicationDb", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    public DbSet<CarModel> Cars { get; set; }

    public override IDbSet<ApplicationUser> Users { get; set; }

    public void MarkAsModified(CarModel car)
    {
        Entry(car).State = EntityState.Modified;
    }
}

一些类是使用Visual Studios“快速操作”通过自动更正形成的。任何人都可以解释为什么ApplicationUser模型需要IDbSet,但CarModels仅需要DbSet,以及为什么Users类中的ApplicationDbContext需要覆盖?

1 个答案:

答案 0 :(得分:0)

  

有人可以解释为什么ApplicationUser模型需要IDbSet,但CarModels只需要DbSet

设计

IdentityDbContext classUsersRoles属性使用了IDbSet<TEntity>

public virtual IDbSet<TUser> Users { get; set; }
public virtual IDbSet<TRole> Roles { get; set; }

在您的情况下,您可以遵循相同的模式

public virtual IDbSet<CarModel> Cars { get; set; }

并更新您的界面以匹配

public interface IApplicationDbContext : IDisposable {
    IDbSet<ApplicationUser> Users { get; set; }
    IDbSet<CarModel> Cars { get; set; }
    int SaveChanges();
    void MarkAsModified(CarModel car);
}

然后可以安全地模拟接口以进行隔离单元测试,前提是接口被注入被测试对象。<​​/ p>

  

为什么ApplicationDbContext类中的用户需要覆盖?

实际上并不需要重写它,因为类的通用性质(即IdentityDbContext<ApplicationUser>)已经使属性遵循提供的ApplicationUser类型。你可以轻易地将它排除在外。

public class ApplicationDbContext 
    : IdentityDbContext<ApplicationUser>, IApplicationDbContext {

    public ApplicationDbContext()
        : base("ApplicationDb", throwIfV1Schema: false) {
    }

    public static ApplicationDbContext Create() {
        return new ApplicationDbContext();
    }

    public virtual IDbSet<CarModel> Cars { get; set; }

    public void MarkAsModified(CarModel car) {
        Entry(car).State = EntityState.Modified;
    }
}