gpt4 book ai didi

c# - 如何防止在单元测试中自动包含导航属性

转载 作者:太空宇宙 更新时间:2023-11-03 12:00:05 24 4
gpt4 key购买 nike

我目前正在开发一个应用商店风格的 API,它具有以下实体(加上许多其他实体,但与问题无关):

  • 应用(与 AppRevision 的一对多关系 - 包含 IEnumerable 属性)
  • 应用修订
  • 安装

我遇到了一个奇怪的问题,即 EF 在单元测试中的行为与实际运行 API 时的行为不同,因为在单元测试时会自动包含导航属性。

从我的命令处理程序中获取以下代码片段:

App app = await this.context.Apps
.Include(a => a.Installations)
.FirstOrDefaultAsync(a => a.Id == command.AppId);

if (app != null) {
// Code omitted for brevity
}

运行 API 时,如果我在运行此代码后检查 app,App 实体上的 AppRevisions 集合为空,正如您所期望的那样,因为我没有明确告诉 EF .Include(a => a.AppRevisions) - 当稍后尝试处理需要此数据的代码时,API 会抛出异常。

现在查看同一处理程序的以下单元测试:

[Fact]
public async void Handle_ShouldAddInstallationRecord_WhenDataIsValid()
{
Guid testGuid = Guid.NewGuid();

CreateInstallationCommand command = new CreateInstallationCommand(testGuid, "ABC", "abc@abc.com", null);

using (TestContext context = new TestContextFactory().CreateTestContext())
{
context.Apps.Add(new App() { Id = testGuid });
context.AppRevisions.Add(new AppRevision() { Id = Guid.NewGuid(), AppId = testGuid, Status = AppRevisionStatus.Approved, IsListed = true });
await context.SaveChangesAsync();

CreateInstallationCommandHandler handler = new CreateInstallationCommandHandler(context);

CommandResult result = await handler.Handle(command, new CancellationToken());

Assert.True(result);
Assert.Single(context.Installations);
}
}

如果我逐步完成此测试,当我到达处理程序并检查 app 变量时,AppRevisions 集合已自动填充。结果,测试通过了,因为需要填充 AppRevisions 集合的代码可以执行。

期望此测试实际上应该失败,因为我没有告诉 EF 在查询中包含这些实体。

我在内存数据库中使用 Sqlite 为我的单元测试创​​建数据库上下文并运行 .NET Core 2.2

我最初认为这与 changetracker 有关。虽然禁用它确实解决了上面报告的直接问题,但它会产生大量其他问题,因此不是一个可行的解决方案(而且可能无论如何都不是正确的解决方案)

感谢收到的任何建议

最佳答案

对于以后遇到这篇文章的任何人,解决方案是根据对原始问题的评论,使用单独的上下文来播种测试数据并在测试后期获取数据:

[Fact]
public async void Handle_ShouldAddInstallationRecord_WhenDataIsValid()
{
Guid testGuid = Guid.NewGuid();

CreateInstallationCommand command = new CreateInstallationCommand(testGuid, "ABC", "abc@abc.com", null);

using (TestContextFactory contextFactory = new TestContextFactory())
{
using (TestContext seedContext = contextFactory.CreateTestContext())
{
seedContext.Apps.Add(new App() { Id = testGuid });
seedContext.AppRevisions.Add(new AppRevision() { Id = Guid.NewGuid(), AppId = testGuid, Status = AppRevisionStatus.Approved, IsListed = true });
await seedContext.SaveChangesAsync();
}

using (TestContext getContext = contextFactory.CreateTestContext())
{
CreateInstallationCommandHandler handler = new CreateInstallationCommandHandler(getContext);

CommandResult result = await handler.Handle(command, new CancellationToken());

Assert.True(result);
Assert.Single(getContext.Installations);
}
}
}

关于c# - 如何防止在单元测试中自动包含导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57426788/

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