我想單元測試從嘲笑DbContext
存儲庫的檢索方法,但我不能將模擬DbSet
值設置到存儲庫。模擬DbSet <TEntity>存儲庫中
資源庫看起來是這樣的:
public class ChangeLogRepository : Repository<ChangeLog>, IChangeLogRepository
{
public ChangeLogRepository(IDbContext context, long tenantId) : base(context, tenantId)
{
}
}
的基類:
public class Repository<TEntity> where TEntity : class {
protected readonly IDbContext Context;
protected DbSet<TEntity> Entities { get; set; }
public long TenantId { get; set; }
protected Repository(IDbContext context, long tenant)
{
Context = context;
TenantId = tenant;
Entities = Context.Set<TEntity>();
}
public List<TEntity> GetAll()
{
return Entities.ToList();
}
//..
}
最後但並非最不重要的,測試類:
[TestClass]
public class ChangeLogRepository_Test
{
private ChangeLogRepository repository;
private List<ChangeLog> allTestData;
[TestInitialize]
public void TestInitialize()
{
var dbContext = new Mock<IDbContext>();
allTestData = new List<ChangeLog>() {
new ChangeLog { Id = 10, EntityName = "User",PropertyName = "UserName",PrimaryKeyValue = 1,OldValue = "Max",NewValue = "Moritz",DateChanged = DateTime.Now,FieldType = ChangeLogFieldType.Default },
new ChangeLog { Id = 10, EntityName = "User",PropertyName = "CreatedAt",PrimaryKeyValue =2,OldValue = "15/06/2017",NewValue = "15/06/2017",DateChanged = DateTime.Now,FieldType = ChangeLogFieldType.Date },
new ChangeLog { Id = 10, EntityName = "Role",PropertyName = "RoleName",PrimaryKeyValue = 56,OldValue = "Admin",NewValue = "Administrator",DateChanged = DateTime.Now,FieldType = ChangeLogFieldType.Default },
};
var changelogs = MockDbSet(allTestData);
dbContext.Setup(m => m.Set<ChangeLog>()).Returns(() => changelogs);
repository = new ChangeLogRepository(dbContext.Object, 10);
}
[TestMethod]
public void Setup_Test()
{
Assert.AreEqual(repository.GetAll(), allTestData);
}
private static 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());
return dbSetMock.Object;
}
}
如果我運行它,則測試失敗,因爲getAll()
方法會返回null。它接縫,該物業'實體'沒有被嘲弄的Set()
方法正確初始化。
當我在存儲庫構造函數 中設置斷點並檢查實體屬性時,在「表達式>值>結果視圖」下出現三個條目。在第一個結果視圖下,有一個「枚舉不會產生結果」消息,兩行使用?在它(Visual Studio 2017)中。
如何正確嘲笑存儲庫中的實體?我究竟做錯了什麼?