gpt4 book ai didi

c# - 在存储库中模拟 DbSet

转载 作者:行者123 更新时间:2023-11-30 12:21:40 24 4
gpt4 key购买 nike

我想对存储库中的检索方法进行单元测试,该存储库具有模拟的 DbContext,但我无法将模拟的 DbSet 值设置到存储库。

存储库如下所示:

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() 方法没有正确初始化属性“Entities”。

当我在 repository-constructor 中设置断点时并检查 Entities 属性,在“Expression > Value > Result View”下出现三个条目。在第一个结果 View 下有一个“枚举没有产生结果”消息和两行?在其中(Visual Studio 2017)。

如何正确模拟存储库中的实体?我做错了什么?

最佳答案

我完全根据原始问题中提供的示例重新创建了测试,但无法重现 null 问题。模拟返回一个已填充的集合,就像它配置的那样。

但是在比较两个集合时出现了问题,

Assert.AreEqual(repository.GetAll(), allTestData);

他们不被认为是平等的。预期,因为 ToList 将创建一个新列表,这显然是对用作模拟数据源的原始列表的不同引用。

使用 CollectionAssert.AreEquivalent 比较两个集合

[TestMethod]
public void Setup_Test() {
var actual = repository.GetAll();
CollectionAssert.AreEquivalent(allTestData, actual);
}

测试通过。

关于c# - 在存储库中模拟 DbSet<TEntity>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44827247/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com