Xunit 内存数据库中的新 DBContext 类具有实时数据
Posted
技术标签:
【中文标题】Xunit 内存数据库中的新 DBContext 类具有实时数据【英文标题】:Xunit new in memory database DBContext Class has live data 【发布时间】:2021-03-07 15:18:27 【问题描述】:我正在尝试使用 EF Core 内存数据库进行单元测试,如下所示:
namespace ContosoTests
public class TrendServiceTests
private static Microsoft.EntityFrameworkCore.DbContextOptions<TestContext> options = new
Microsoft.EntityFrameworkCore.DbContextOptionsBuilder<TestContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
private static TestContext _context = new TestContext(options);
private readonly TrendService trendService = new TrendService(_context);
private void SeedInMemoryDb()
if (!_context.TrendHistories.Any())
_context.TrendHistories.Add(new TrendHistory IsActive = true, Quarter = E_Quarter.Q1,
TrendYear = 2020 );
if (!_context.Controls.Any())
_context.Controls.Add(new Control IsActive = true);
_context.Controls.Add(new Control IsActive = true);
_context.Controls.Add(new Control IsActive = false);
_context.SaveChanges();
我的 TestContext 继承自我的实时上下文类以避免错误:数据库提供程序“Microsoft.EntityFrameworkCore.InMemory”、“Microsoft.EntityFrameworkCore.SqlServer”的服务已在服务提供程序中注册。一个服务提供者只能注册一个数据库提供者
所以我的 TestContext 看起来像:
public class TestContext : ContosoContext
public TestContext(DbContextOptions<TestContext> options)
public TestContext()
当我在测试类中使用新的 TestContext (_context) 实例时,ContosoContext 的所有实时数据都在那里。 我期待它是没有数据的上下文类的新实例,以便我可以使用受控数据测试我的 DAL 代码。但这种情况并非如此。 我对单元测试还很陌生,因此非常感谢任何帮助。
编辑: 这是我的 contoso 上下文类的相关部分
public class ContosoContext: IdentityDbContext<ContosoApplicationUser>
public ContosoContext(DbContextOptions<ContosoContext> options) : base
(options)
public ContosoContext()
//all my DBSets here
protected override void OnConfiguring(DbContextOptionsBuilder
optionsBuilder)
optionsBuilder.UseSqlServer("MyConnectionString");
所以问题是我的onconfiguring方法直接处理连接字符串??
【问题讨论】:
您的ContosoContext
似乎对ServiceProvider
做了一些奇怪的事情。 ContosoContext
应该完全依赖注入的DbContextOptions
来配置连接。因此,如果不显式注入包含“实时”连接字符串的配置,它应该无法连接到该数据库。如果您将ContosoContext
的内容(或至少相关部分)复制到问题中,可能会有所帮助。 :)
另外,一般来说你不需要TestContext
。如果我正确理解被测系统是ContosoContext
,您应该直接使用它来使测试代表您的实时系统(相对于给定组件)。另外,TestContext
中的构造函数目前没有对 db 配置做任何事情。但如果我们看到您的ContosoContext
,可能一切都会清楚。 (这很可能足以发布有用的答案。)
哦,我现在看到 TrendService
是 SUT。显然,我是个盲人。但是要对其进行单元测试,您需要将其与其他组件隔离开来,这意味着您将模拟ContosoContext
。测试多个组件更像是集成测试(这也很好,实际上会给你更高的信心)。无论如何,请出示您的ContosoContext
,我们可以从那里继续。 :P
【参考方案1】:
要修复错误,您需要在OnConfiguring
方法中删除optionsBuilder.UseSqlServer("MyConnectionString");
或避免注册多个数据库提供程序,将其更改为:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
if(!optionsBuilder.IsConfigured)
optionsBuilder.UseSqlServer("MyConnectionString");
【讨论】:
你说得对,这解决了我的问题,现在我可以取消我正在使用的 TestContext 类 是的,你不需要额外的TestContext
以上是关于Xunit 内存数据库中的新 DBContext 类具有实时数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在需要 UserManager 但使用内存数据库的 XUnit 中测试方法
如何根据 XUnit 测试隔离 EF InMemory 数据库