C# 如何在WebApplicationFactory中设置SQLite?
我正在为我的ASP.NET核心MVC应用程序编写一个集成测试。测试将向控制器发送C# 如何在WebApplicationFactory中设置SQLite?,c#,sqlite,integration-testing,asp.net-core-3.1,in-memory-database,C#,Sqlite,Integration Testing,Asp.net Core 3.1,In Memory Database,我正在为我的ASP.NET核心MVC应用程序编写一个集成测试。测试将向控制器发送POST请求,然后检查数据库是否正确更新 我有一个CustomWebApplicationFactory,试图在内存数据库中配置SQLite,但可能我做错了什么 public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class { pri
POST
请求,然后检查数据库是否正确更新
我有一个CustomWebApplicationFactory
,试图在内存数据库中配置SQLite,但可能我做错了什么
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
private SqliteConnection Connection;
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
Connection = new SqliteConnection("DataSource=:memory:");
Connection.Open();
builder.UseEnvironment("Development");
builder.ConfigureTestServices(services =>
{
// Unregister existing database service (SQL Server).
var descriptor = services.SingleOrDefault(
d => d.ServiceType ==
typeof(DbContextOptions<AppDbContext>));
if (descriptor != null) services.Remove(descriptor);
// Register new database service (SQLite In-Memory)
services.AddDbContext<AppDbContext>(options => options.UseSqlite(Connection));
});
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Connection.Close();
}
}
公共类CustomWebApplicationFactory:WebApplicationFactory,其中TStartup:class
{
私有连接;
受保护的覆盖无效配置WebHost(IWebHostBuilder)
{
连接=新的SqliteConnection(“数据源=:内存:”);
Connection.Open();
建筑商。使用环境(“开发”);
builder.ConfigureTestServices(服务=>
{
//注销现有数据库服务(SQL Server)。
变量描述符=services.SingleOrDefault(
d=>d.ServiceType==
typeof(DbContextOptions));
if(描述符!=null)服务。删除(描述符);
//注册新数据库服务(内存中的SQLite)
services.AddDbContext(options=>options.UseSqlite(Connection));
});
}
受保护的覆盖无效处置(布尔处置)
{
基地。处置(处置);
Connection.Close();
}
}
我的测试如下所示:
public class OrderControllerTests : IClassFixture<CustomWebApplicationFactory<Startup>>
{
private readonly HttpClient _httpClient;
private readonly AppDbContext _context;
public OrderControllerTests(CustomWebApplicationFactory<Startup> factory)
{
_httpClient = factory.CreateDefaultClient();
var scopeFactory = factory.Services.GetService<IServiceScopeFactory>();
using var scope = scopeFactory.CreateScope();
_context = scope.ServiceProvider.GetService<AppDbContext>();
}
[Fact]
public async Task Create_Post_OrderIsCreated()
{
// ...
_context.Customers.Add(customer);
_context.SaveChanges();
// ...
}
}
公共类OrderControllerTests:IClassFixture
{
私有只读HttpClientu HttpClient;
私有只读AppDbContext\u上下文;
public OrderControllerTests(CustomWebApplicationFactory)
{
_httpClient=factory.CreateDefaultClient();
var scopeFactory=factory.Services.GetService();
使用var scope=scopeFactory.CreateScope();
_context=scope.ServiceProvider.GetService();
}
[事实]
公共异步任务创建\发布\订单创建()
{
// ...
_context.Customers.Add(客户);
_SaveChanges();
// ...
}
}
当我运行测试时,行\u context.Customers.Add(customer)
触发CustomWebApplicationFactory.Dispose()方法,我得到一个错误:
System.ObjectDisposedException:无法访问已释放的上下文实例。此错误的一个常见原因是处理通过依赖项注入解析的上下文实例,然后在应用程序的其他位置尝试使用相同的上下文实例。如果对上下文实例调用“Dispose”,或将其包装到using语句中,则可能会发生这种情况。如果您使用的是依赖项注入,那么应该让依赖项注入容器处理上下文实例
对象名称:“AppDbContext”
这个错误消息非常具有描述性,但我不知道如何解决它。为什么要处理数据库上下文?我想我已经弄明白了,问题是
\u context
仅在\u范围内可用,所以我使用删除了,现在我在类测试之间共享了数据库。每个测试都有清空和填充数据库的选项
private readonly HttpClient _httpClient;
private readonly AppDbContext _context;
private readonly IServiceScope _scope;
public OrderControllerTests(CustomWebApplicationFactory<Startup> factory)
{
_httpClient = factory.CreateDefaultClient();
_scope = (factory.Services.GetRequiredService<IServiceScopeFactory>()).CreateScope();
_context = _scope.ServiceProvider.GetRequiredService<AppDbContext>();
// database is now shared across tests
_context.Database.EnsureCreated();
}
private readonly HttpClient\u HttpClient;
私有只读AppDbContext\u上下文;
专用只读iSeries示波器_范围;
public OrderControllerTests(CustomWebApplicationFactory)
{
_httpClient=factory.CreateDefaultClient();
_scope=(factory.Services.GetRequiredService()).CreateScope();
_上下文=_scope.ServiceProvider.GetRequiredService();
//数据库现在在测试之间共享
_context.Database.recreated();
}