使用关系数据,架构和事务测试EF Core

问题描述 投票:0回答:1

我在使用EF Core(2.0.1)创建单元测试时遇到问题。

我使用以下选项创建数据库:

var options = new DbContextOptionsBuilder<MyContext>()
    .UseInMemoryDatabase(Guid.NewGuid().ToString())
    .ConfigureWarnings((b) =>
    {
        b.Ignore(InMemoryEventId.TransactionIgnoredWarning);
    })
    .Options; 

我要测试的代码看起来像这样:

using (IDbContextTransaction transaction = await context.Database.BeginTransactionAsync())
{
    await context.Database.ExecuteSqlCommandAsync("DELETE FROM fooSchema.Customers WHERE ID = {0}", id);
    await context.SaveChangesAsync();

    // Other stuff...

    context.Customers.Add(fooCustomer);
    await context.SaveChangesAsync();
 }

首先,我遇到了InMemory不支持事务的问题。如代码所示,我使用ConfigureWarnings解决了该问题。但是,事实证明InMemory无法处理ExecuteSqlCommandAsync。因此,我尝试了SQLLite,但它不处理自定义架构。

我如何在没有任何“真实” DB的情况下创建一个DbContext来处理事务,架构和ExecuteSqlCommandAsync?

可以抑制来自ExecuteSqlCommandAsync的错误。但是我找不到它的EventId。实际上,它的效果很好,这仅用于单元测试。

entity-framework ef-core-2.0
1个回答
0
投票

您可以配置Sqlite内存来测试关系数据库。 https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/sqlite

我一直在尝试测试类似的情况:

public async Task Test()
    {
        // In-memory database only exists while the connection is open
        var connection = new SqliteConnection("DataSource=:memory:");
        connection.Open();

        try
        {
            var options = new DbContextOptionsBuilder<TestDbContext>()
                .UseSqlite(connection)
                .Options;

            // Create the schema in the database
            using (var context = new TestDbContext(options))
            {
                context.Database.EnsureCreated();
                await context.Database.ExecuteSqlCommandAsync($"INSERT INTO [MySchema].[MyTable] (col1, col2) VALUES (1, 'derp')",
                                                                         default(CancellationToken));
            }

            // Run the test against one instance of the context
            using (var context = new TestDbContext(options))
            {
                var val = context.MyTable.FirstOrDefault();
                // This should return the inserted value
            }
        }
        finally
        {
            connection.Close();
        }
    }

但是我发现这条线

await context.Database.ExecuteSqlCommandAsync($"INSERT INTO [MySchema].[MyTable] (col1, col2) VALUES (1, 'derp')", default(CancellationToken));

可能是问题所在。仅当我离开这样的模式名称时,我才能使它工作:

await context.Database.ExecuteSqlCommandAsync($"INSERT INTO [MyTable] (col1, col2) VALUES (1, 'derp')", default(CancellationToken));

我不确定为什么包含架构会导致以下错误:

“ Microsoft.Data.Sqlite.SqliteException:SQLite错误1:'没有这样的表:MySchema.MyTable'。”

© www.soinside.com 2019 - 2024. All rights reserved.