我有几个上下文的通用存储库。我可以扩展它并将它用于服务而没有问题。但是,当我嘲笑它时,构造函数中的this.Entities
总是null
。
GenericDataRepsository
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和Nsubstitute。也试过Moq,同样的问题。那么,为什么没有设定Entities
?
答案 0 :(得分:3)
您没有使用方法set<T>
将模拟对象设置为返回任何值。
在初始化测试类之前,只需添加以下调用:
mockContext.Set<BillTo>().Returns(mockSet);
答案 1 :(得分:1)
为什么要使用FindBy方法?为什么不使用FindAll()返回this.Entities = context.Set()之类的内容
public IQueryable<T> FindAll()
{
return _context.Set<T>());
}
然后,存储库的用户可以使用他们想要的任何linq谓词 并且您可以模拟或伪造FindAll()方法以返回您想要的任何实体列表。