gpt4 book ai didi

entity-framework-core - 让 EF Core 将 SQL 语句输出到 xUnit 的 ITestOutputHelper

转载 作者:行者123 更新时间:2023-12-04 08:37:59 27 4
gpt4 key购买 nike

我正在使用 EF Core 2.2.4 并试图找出 EF Core 在我们的单元测试中发送到我们的 SQLite 数据库的 SQL 语句。由于我们使用的是 xUnit (2.4.1),我们必须将日志消息写入 ITestOutputHelper xUnit 实例正在注入(inject)我们的测试类而不是控制台。对于控制台,我找到了这段代码:

private static ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder =>
builder.AddConsole()
.AddFilter(DbLoggerCategory.Database.Command.Name,
LogLevel.Information));
return serviceCollection.BuildServiceProvider()
.GetService<ILoggerFactory>();
}

如何将此输出重定向到 ITestOutputHelper.WriteLine()

最佳答案

首先,创建一些样板日志记录代码以允许输出到 ITestOutputHelper:

class TestLoggerProvider : ILoggerProvider
{
ITestOutputHelper _output;

public TestLoggerProvider(ITestOutputHelper output)
=> _output = output;

public ILogger CreateLogger(string categoryName)
=> new TestLogger(categoryName, _output);

public void Dispose()
{
}
}

class TestLogger : ILogger
{
string _categoryName;
ITestOutputHelper _output;

public TestLogger(string categoryName, ITestOutputHelper output)
{
_categoryName = categoryName;
_output = output;
}

public bool IsEnabled(LogLevel logLevel)
// NB: Only logging things related to commands, but you can easily expand
// this
=> _categoryName == DbLoggerCategory.Database.Command.Name;

public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
// TODO: Customize the formatting even more if you want
//if (eventId == RelationalEventId.CommandExecuting)
//{
// var structure = (IReadOnlyList<KeyValuePair<string, object>>)state;
// var parameters = (string)structure.First(i => i.Key == "parameters")
// .Value;
// var commandText = (string)structure.First(i => i.Key == "commandText")
// .Value;
//}

_output.WriteLine(formatter(state, exception));
}

public IDisposable BeginScope<TState>(TState state)
=> null;
}

接下来,确保您的 DbContext 可以接受外部选项。

class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{
}
}

最后,把它连接起来。下面是为每个测试创建一个新上下文的示例。使用 classcollection fixture以延长上下文的生命周期。

public class UnitTest1 : IDisposable
{
IServiceProvider _serviceProvider;
MyDbContext _db;

public UnitTest1(ITestOutputHelper output)
{
_serviceProvider = new ServiceCollection()
.AddLogging(x => x.AddProvider(new TestLoggerProvider(output)))
.AddEntityFrameworkSqlite()
.BuildServiceProvider();

_db = new MyDbContext(
new DbContextOptionsBuilder<MyDbContext>()
// Don't call UseLoggerFactory! (a new service provider would be
// created every time without ever getting disposed)
.UseInternalServiceProvider(_serviceProvider)
.UseSqlite("Data Source=:memory:")
.Options);
}

[Fact]
public void Test1()
{
_db.Database.ExecuteSqlRaw("-- Can you see me?");
}

public void Dispose()
{
_db.Dispose();
(_serviceProvider as IDisposable)?.Dispose();
}
}

关于entity-framework-core - 让 EF Core 将 SQL 语句输出到 xUnit 的 ITestOutputHelper,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61673470/

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