-
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>$(LatestTargetFrameworks);netstandard2.0</TargetFrameworks> | ||
<IsTrimmable>false</IsTrimmable> | ||
|
||
<Description>Microsoft.Extension.Logging.ILogger implementation for xunit.v3</Description> | ||
<PackageTags>xunit, xunit.v3, logger</PackageTags> | ||
<Version>1.0.0</Version> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" /> | ||
<PackageReference Include="xunit.v3.extensibility.core" Version="1.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
using System.Text; | ||
using Microsoft.Extensions.Logging; | ||
using Xunit; | ||
|
||
namespace Meziantou.Extensions.Logging.Xunit.v3; | ||
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / create_nuget
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (macos-14, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (ubuntu-22.04, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Debug, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
Check failure on line 5 in src/Meziantou.Extensions.Logging.Xunit.v3/XUnitLogger.cs GitHub Actions / build_and_test_x64 (windows-2022, Release, /p:InvariantGlobalization=true)
|
||
|
||
public sealed class XUnitLogger<T> : XUnitLogger, ILogger<T> | ||
{ | ||
public XUnitLogger(ITestOutputHelper testOutputHelper, LoggerExternalScopeProvider scopeProvider) | ||
: base(testOutputHelper, scopeProvider, typeof(T).FullName) | ||
{ | ||
} | ||
} | ||
|
||
public class XUnitLogger : ILogger | ||
{ | ||
private readonly ITestOutputHelper _testOutputHelper; | ||
private readonly string? _categoryName; | ||
private readonly XUnitLoggerOptions _options; | ||
private readonly LoggerExternalScopeProvider _scopeProvider; | ||
|
||
public static ILogger CreateLogger(ITestOutputHelper testOutputHelper) => new XUnitLogger(testOutputHelper, new LoggerExternalScopeProvider(), ""); | ||
public static ILogger<T> CreateLogger<T>(ITestOutputHelper testOutputHelper) => new XUnitLogger<T>(testOutputHelper, new LoggerExternalScopeProvider()); | ||
|
||
public XUnitLogger(ITestOutputHelper testOutputHelper, LoggerExternalScopeProvider scopeProvider, string? categoryName) | ||
: this(testOutputHelper, scopeProvider, categoryName, appendScope: true) | ||
{ | ||
} | ||
|
||
public XUnitLogger(ITestOutputHelper testOutputHelper, LoggerExternalScopeProvider scopeProvider, string? categoryName, bool appendScope) | ||
: this(testOutputHelper, scopeProvider, categoryName, options: new XUnitLoggerOptions { IncludeScopes = appendScope }) | ||
{ | ||
} | ||
|
||
public XUnitLogger(ITestOutputHelper testOutputHelper, LoggerExternalScopeProvider scopeProvider, string? categoryName, XUnitLoggerOptions? options) | ||
{ | ||
_testOutputHelper = testOutputHelper; | ||
_scopeProvider = scopeProvider; | ||
_categoryName = categoryName; | ||
_options = options ?? new(); | ||
} | ||
|
||
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; | ||
|
||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => _scopeProvider.Push(state); | ||
|
||
[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs")] | ||
[SuppressMessage("Usage", "MA0011:IFormatProvider is missing")] | ||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) | ||
{ | ||
var sb = new StringBuilder(); | ||
|
||
if (_options.TimestampFormat is not null) | ||
{ | ||
var now = _options.UseUtcTimestamp ? DateTimeOffset.UtcNow : DateTimeOffset.Now; | ||
var timestamp = now.ToString(_options.TimestampFormat); | ||
sb.Append(timestamp).Append(' '); | ||
} | ||
|
||
if (_options.IncludeLogLevel) | ||
{ | ||
sb.Append(GetLogLevelString(logLevel)).Append(' '); | ||
} | ||
|
||
if (_options.IncludeCategory) | ||
{ | ||
sb.Append('[').Append(_categoryName).Append("] "); | ||
} | ||
|
||
sb.Append(formatter(state, exception)); | ||
|
||
if (exception is not null) | ||
{ | ||
sb.Append('\n').Append(exception); | ||
} | ||
|
||
// Append scopes | ||
if (_options.IncludeScopes) | ||
{ | ||
_scopeProvider.ForEachScope((scope, state) => | ||
{ | ||
state.Append("\n => "); | ||
state.Append(scope); | ||
}, sb); | ||
} | ||
|
||
try | ||
{ | ||
_testOutputHelper.WriteLine(sb.ToString()); | ||
} | ||
catch | ||
{ | ||
// This can happen when the test is not active | ||
} | ||
} | ||
|
||
private static string GetLogLevelString(LogLevel logLevel) | ||
{ | ||
return logLevel switch | ||
{ | ||
LogLevel.Trace => "trce", | ||
LogLevel.Debug => "dbug", | ||
LogLevel.Information => "info", | ||
LogLevel.Warning => "warn", | ||
LogLevel.Error => "fail", | ||
LogLevel.Critical => "crit", | ||
_ => throw new ArgumentOutOfRangeException(nameof(logLevel)) | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
namespace Meziantou.Extensions.Logging.Xunit.v3; | ||
|
||
public sealed class XUnitLoggerOptions | ||
{ | ||
/// <summary> | ||
/// Includes scopes when <see langword="true" />. | ||
/// </summary> | ||
public bool IncludeScopes { get; set; } | ||
|
||
/// <summary> | ||
/// Includes category when <see langword="true" />. | ||
/// </summary> | ||
public bool IncludeCategory { get; set; } | ||
|
||
/// <summary> | ||
/// Includes log level when <see langword="true" />. | ||
/// </summary> | ||
public bool IncludeLogLevel { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets format string used to format timestamp in logging messages. Defaults to <see langword="null" />. | ||
/// </summary> | ||
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)] | ||
public string? TimestampFormat { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets indication whether or not UTC timezone should be used to format timestamps in logging messages. Defaults to <see langword="false" />. | ||
/// </summary> | ||
public bool UseUtcTimestamp { get; set; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Xunit; | ||
|
||
namespace Meziantou.Extensions.Logging.Xunit.v3; | ||
|
||
public sealed class XUnitLoggerProvider : ILoggerProvider | ||
{ | ||
private readonly ITestOutputHelper _testOutputHelper; | ||
private readonly XUnitLoggerOptions _options; | ||
private readonly LoggerExternalScopeProvider _scopeProvider = new(); | ||
|
||
public XUnitLoggerProvider(ITestOutputHelper testOutputHelper) | ||
: this(testOutputHelper, options: null) | ||
{ | ||
} | ||
|
||
public XUnitLoggerProvider(ITestOutputHelper testOutputHelper, bool appendScope) | ||
: this(testOutputHelper, new XUnitLoggerOptions { IncludeScopes = appendScope }) | ||
{ | ||
} | ||
|
||
public XUnitLoggerProvider(ITestOutputHelper testOutputHelper, XUnitLoggerOptions? options) | ||
{ | ||
_testOutputHelper = testOutputHelper; | ||
_options = options ?? new XUnitLoggerOptions(); | ||
} | ||
|
||
public ILogger CreateLogger(string categoryName) | ||
{ | ||
return new XUnitLogger(_testOutputHelper, _scopeProvider, categoryName, _options); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Meziantou.Extensions.Logging.Xunit.v3 | ||
|
||
```c# | ||
ILogger logger = XUnitLogger.CreateLogger(); | ||
ILogger<MyType> logger = XUnitLogger.CreateLogger<MyType>(); | ||
``` | ||
|
||
If you are using a `WebApplicationFactory`: | ||
|
||
```c# | ||
public class UnitTest1(ITestOutputHelper testOutputHelper) | ||
{ | ||
[Fact] | ||
public async Task Test1() | ||
{ | ||
using var factory = new WebApplicationFactory<Program>() | ||
.WithWebHostBuilder(builder => | ||
{ | ||
builder.ConfigureLogging(builder => | ||
{ | ||
// You can override the logging configuration if needed | ||
//builder.SetMinimumLevel(LogLevel.Trace); | ||
//builder.AddFilter(_ => true); | ||
// Register the xUnit logger provider | ||
builder.Services.AddSingleton<ILoggerProvider>(new XUnitLoggerProvider(testOutputHelper, appendScope: false)); | ||
}); | ||
}); | ||
} | ||
} | ||
``` | ||
|
||
Blog post about this package: [How to write logs from ILogger to xUnit.net ITestOutputHelper](https://www.meziantou.net/how-to-view-logs-from-ilogger-in-xunitdotnet.htm) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System.Globalization; | ||
using Xunit; | ||
|
||
namespace Meziantou.Extensions.Logging.Xunit.v3.Tests; | ||
|
||
internal sealed class InMemoryTestOutputHelper : ITestOutputHelper | ||
{ | ||
private readonly List<string> _logs = new(); | ||
|
||
public IEnumerable<string> Logs => _logs; | ||
|
||
public string Output { get; } | ||
|
||
public void Write(string message) | ||
{ | ||
lock (_logs) | ||
{ | ||
_logs.Add(message); | ||
} | ||
} | ||
|
||
public void Write(string format, params object[] args) | ||
{ | ||
lock (_logs) | ||
{ | ||
_logs.Add(string.Format(CultureInfo.InvariantCulture, format, args)); | ||
} | ||
} | ||
|
||
public void WriteLine(string message) | ||
{ | ||
lock (_logs) | ||
{ | ||
_logs.Add(message + Environment.NewLine); | ||
} | ||
} | ||
|
||
public void WriteLine(string format, params object[] args) | ||
{ | ||
lock (_logs) | ||
{ | ||
_logs.Add(string.Format(CultureInfo.InvariantCulture, format, args) + Environment.NewLine); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>$(LatestTargetFrameworks)</TargetFrameworks> | ||
<IncludeDefaultTestReferences>false</IncludeDefaultTestReferences> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> | ||
<PackageReference Include="xunit.v3" Version="1.0.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Meziantou.Extensions.Logging.Xunit.v3\Meziantou.Extensions.Logging.Xunit.v3.csproj" /> | ||
</ItemGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#pragma warning disable CA1848 // Use the LoggerMessage delegates | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
using Xunit; | ||
using Meziantou.Extensions.Logging.Xunit; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Meziantou.Extensions.Logging.Xunit.v3.Tests; | ||
|
||
public sealed class XunitLoggerTests | ||
{ | ||
[Fact] | ||
public void XUnitLoggerProviderTest() | ||
{ | ||
var output = new InMemoryTestOutputHelper(); | ||
using var provider = new XUnitLoggerProvider(output); | ||
var host = new HostBuilder() | ||
.ConfigureLogging(builder => | ||
{ | ||
builder.Services.AddSingleton<ILoggerProvider>(provider); | ||
|
||
}) | ||
.Build(); | ||
|
||
var logger = host.Services.GetRequiredService<ILogger<XunitLoggerTests>>(); | ||
logger.LogInformation("Test"); | ||
logger.LogInformation("Test {Sample}", "value"); | ||
|
||
Assert.Equal(["Test" + Environment.NewLine, "Test value" + Environment.NewLine], output.Logs); | ||
} | ||
} |