gpt4 book ai didi

c# - Moq 枚举在 FirstOrDefault 上消失

转载 作者:行者123 更新时间:2023-12-02 04:12:46 25 4
gpt4 key购买 nike

我编写了一个测试来验证一小部分新功能,该功能调用一个大型中间件函数,其中包含大量逻辑,将一种类型的用户(ASP Net Membership User)转换为内部类型(SystemUser) 。这是一个困惑的系统,但我无法将其撕掉,因此需要进行新的测试。

我的测试调用 GetAllActiveUsers()方法向下调用几层并最终到达导致问题的枚举。该测试有一个模拟的 Entity Framework 数据上下文 Mock<localEntities> mockDb设置如下:

[SetUp]
public void Setup()
{
var mockUserSet = new Mock<DbSet<User>>();

this.mockDb = new Mock<localEntities>();
this.mockMembershipService = new Mock<IMembershipService>();
this.mockRoleService = new Mock<IRoleService>();
this.mockUserAgreementRelation = new Mock<DbSet<UserAgreementRelation>>();

this.testUsers = this.CreateSystemUsers();

this.mockDb.Setup(m => m.User).Returns(mockUserSet.Object);

mockUserAgreementRelation.SetupAllProperties();

var agreementRelations = this.testUsers.Select(u => new UserAgreementRelation() { AgentUserID = u.UserId, IsDeleted = null });

mockUserAgreementRelation.As<IQueryable<UserAgreementRelation>>().Setup(ua => ua.GetEnumerator()).Returns(agreementRelations.GetEnumerator());
this.mockDb.Setup(m => m.UserAgreementRelation).Returns(mockUserAgreementRelation.Object);
}

在我的测试中,我设置了一些用户并调用 var testActiveUsers = testRepo.GetAllActiveUsers();这称为问题线。

这就是我感到困惑的地方。

使用以下代码测试通过:

var agreementRelations = databaseContext.UserAgreementRelation().ToList();

var userAgreementFromDB = agreementRelations
.FirstOrDefault(x => x.AgentUserID == ramsUser.UserId && (x.IsDeleted == null || !(bool)x.IsDeleted));

但此代码失败:

var userAgreementFromDB = databaseContext.UserAgreementRelation
.FirstOrDefault(x => x.AgentUserID == ramsUser.UserId && (x.IsDeleted == null || !(bool)x.IsDeleted));

此外,如果我调试并单步执行代码,我可以对模拟的 UserAgreementRelation 使用一次快速监视。一次。我第一次会看到我正在测试的每个用户的 UserAgreementRelation。如果我再次运行 watch ,即使代码没有前进,枚举也不会产生任何结果。我猜这与问题有关。但是,由于我不知道为什么会发生这种情况,所以我无法说出它是如何导致此问题的。

请记住,更简单的代码(没有 ToList())是生产代码。它目前运行良好,但我的测试失败了。由于这是直接数据库调用,因此枚举整个 UserAgreementRelation 表并不是一个可行的解决方案。

建议?

最佳答案

我不确定我是否遇到了问题,因为您没有提供有关它如何“失败”的详细信息。但也许你应该改变这部分:

.Setup(ua => ua.GetEnumerator()).Returns(agreementRelations.GetEnumerator())

进入:

.Setup(ua => ua.GetEnumerator()).Returns(() => agreementRelations.GetEnumerator())

原因是如果你测试的代码调用GetEnumerator() 不止一次,Moq 不应该分发旧的“已用”枚举器实例,该实例可能已经前进到末尾并且可能已被处置。相反,起订量应该重新运行 Func<> ,我的箭头() => agreementRelations.GetEnumerator() ,获取尚未推进 ( MoveNext() ) 或关闭 ( Dispose() ) 的新枚举器。


提问者告诉我(在下面的评论中)他还需要 Setup属性 Provider Expression IQueryable .

关于c# - Moq 枚举在 FirstOrDefault 上消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35760465/

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