簡體   English   中英

模擬具有上下文的通用存儲庫

[英]Mock Generic Repository with contexts

我有一個用於多個上下文的通用存儲庫。 我可以擴展它並將其用於服務而不會出現問題。 但是,當我模擬它時,構造函數中的this.Entities始終為null

通用數據倉庫

public class GenericDataRepository<T, C> : IGenericDataRepository<T, C> where T : class where C : DbContext, new() {

    protected C context;
    protected IDbSet<T> Entities;

    public GenericDataRepository() {
        this.context = new C();
        this.Entities = context.Set<T>();
    }

    public GenericDataRepository(C context) {
        this.context = context;
        this.Entities = context.Set<T>();  // Problem is here. Entities didn't get set when mocking
    }

    public virtual IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate) {
        return Entities.Where(predicate).ToList();
    }

    // omitted Add, Update, Delte
}

單元測試

 [Test]
    public void GetBIlloTo() {
        var data = new List<BillTo> {
            new BillTo { CONTACTID = 12, COUNTRY = "USA" }
        }.AsQueryable();

        var mockSet = Substitute.For<DbSet<BillTo>, IQueryable<BillTo>>();

        ((IQueryable<BillTo>)mockSet).Provider.Returns(data.Provider);
        ((IQueryable<BillTo>)mockSet).Expression.Returns(data.Expression);
        ((IQueryable<BillTo>)mockSet).ElementType.Returns(data.ElementType);
((IQueryable<BillTo>)mockSet).GetEnumerator().Returns(data.GetEnumerator());

        var mockContext = Substitute.For<MyEntities>();
        mockContext.BillToes.Returns(mockSet);
        var repo = new GenericDataRepository<BillTo, MyEntities>(mockContext);

        //// Act
        var actual = repo.FindBy(r => r.CONTACTID == 12);

        //// Assert
        Assert.AreEqual(actual.Count(), 1);
    }

MyEntities-由EF生成,我沒有更改。

 public partial class MyEntities : DbContext
{
    public MyEntities()
        : base("name=MyEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<BillTo> BillToes { get; set; }
}

我先使用EF數據庫,NUnit和Nsu​​bstitute。 嘗試過起訂量,同樣的問題。 那么,為什么沒有設置Entities

您沒有使用set<T>方法set<T>模擬對象設置為返回任何值。

在初始化要測試的類之前,只需添加以下調用:

mockContext.Set<BillTo>().Returns(mockSet);

為什么根本沒有FindBy方法? 為什么不擁有一個返回this.Entities = context.Set()的FindAll(),例如

public IQueryable<T> FindAll()
{
    return _context.Set<T>());
}

然后,存儲庫的用戶可以添加所需的任何linq謂詞,並且可以模擬或偽造FindAll()方法以返回所需的實體列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM