Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WebApplicationFactory中设置SQLite?_C#_Sqlite_Integration Testing_Asp.net Core 3.1_In Memory Database - Fatal编程技术网

C# 如何在WebApplicationFactory中设置SQLite?

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

我正在为我的ASP.NET核心MVC应用程序编写一个集成测试。测试将向控制器发送
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();
}