如何模拟dbcontext? [英] How to mock up dbcontext?

查看:84
本文介绍了如何模拟dbcontext?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在.net core 1.0 rc2中使用Entity Framework 7.这是课程.

I am using Entity Framework 7 in .net core 1.0 rc2. Here is the class.

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {

    }
    public DbSet<Blog> Blogs { get; set; }
}

然后将ApplicationDbContext注入类

public class BtnValidator
{
    private readonly ApplicationDbContext _dbContext;
    public BtnValidator(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }
}

不确定如何在单元测试方法中对其进行模拟.

Not sure how to mock it in unit test method.

[Fact]
public void Ensure_Proper_Btn_Validated_Return_True()
{
    var dbContext = mockup(ApplicationDbContext); //how

    var validator = new BtnValidator(dbContext);
    var results = validator.IsValid("1234");
    Assure.True(results);
}

编辑

BtnValidator中,我具有访问dbContext的代码.

In BtnValidator, I have code to access the dbContext.

public IsValid(string ID)
{
    var results = _dbContext.Blogs.First(x => x.ID);
    // 
}

推荐答案

您可以抽象化DbContext使其可模拟.

You could abstract your DbContext to make it mockable.

public interface IDbContext {
    DbSet<Blog> Blogs { get; set; }
    //...other properties and members needed for db context
    int SaveChanges();
}

public class ApplicationDbContext : DbContext, IDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) {

    }

    public DbSet<Blog> Blogs { get; set; }
}

然后您可以将合同注入相关类

You can then inject the contract into dependent classes

public class BtnValidator {
    private readonly IDbContext _dbContext;

    public BtnValidator(IDbContext dbContext) {
        _dbContext = dbContext;
    }

    public bool IsValid(string ID) {
        var result = _dbContext.Blogs.FirstOrDefault(x => x.ID == ID);
        return result != null;
    }
}

然后在单元测试中可以模拟接口

and then in your unit tests you can mock the interfaces

[Fact]
public void Ensure_Proper_Btn_Validated_Return_True() {
    //Arrange
    var id = "1234"
    var blogsTestData = new List<Blog>(){ new Blog { ID = id } };
    var blogs = MockDbSet(blogsTestData);
    //Set up mocks for db sets
    var dbContext = new Mock<IDbContext>();        
    dbContext.Setup(m => m.Blogs).Returns(blogs.Object);

    var validator = new BtnValidator(dbContext.Object);

    //Act
    var results = validator.IsValid(id);

    //Assert
    Assure.True(results);
}

Mock<DbSet<T>> MockDbSet<T>(IEnumerable<T> list) where T : class, new() {
    IQueryable<T> queryableList = list.AsQueryable();
    Mock<DbSet<T>> dbSetMock = new Mock<DbSet<T>>();
    dbSetMock.As<IQueryable<T>>().Setup(x => x.Provider).Returns(queryableList.Provider);
    dbSetMock.As<IQueryable<T>>().Setup(x => x.Expression).Returns(queryableList.Expression);
    dbSetMock.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(queryableList.ElementType);
    dbSetMock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(() => queryableList.GetEnumerator());
    dbSetMock.Setup(x => x.Create()).Returns(new T());

    return dbSetMock;
}

这篇关于如何模拟dbcontext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆