Divergic.Logging.Xunit 1.0.0

.NET Standard 2.0
There is a newer version of this package available.
See the version list below for details.
dotnet add package Divergic.Logging.Xunit --version 1.0.0
NuGet\Install-Package Divergic.Logging.Xunit -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Divergic.Logging.Xunit" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Divergic.Logging.Xunit --version 1.0.0
#r "nuget: Divergic.Logging.Xunit, 1.0.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Divergic.Logging.Xunit as a Cake Addin
#addin nuget:?package=Divergic.Logging.Xunit&version=1.0.0

// Install Divergic.Logging.Xunit as a Cake Tool
#tool nuget:?package=Divergic.Logging.Xunit&version=1.0.0

Introduction

Divergic.Logging.Xunit is a NuGet package that returns an ILogger or ILogger<T> provider that wraps around the ITestOutputHelper supplied by xUnit. xUnit uses this helper to write log messages to the test output of each test execution. This means that any log messages from classes being tested will end up in the xUnit test result output.

Installation

Run the following in the NuGet command line or visit the NuGet package page.

Install-Package Divergic.Logging.Xunit

Usage

The common usage of this package is to call the BuildLogger extension method on the xUnit ITestOutputHelper.

using System;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;

public class MyClass
{
    private readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public string DoSomething()
    {
        _logger.LogInformation("Hey, we did something");

        return Guid.NewGuid().ToString();
    }
}

public class MyClassTests
{
    private readonly ITestOutputHelper _output;
    private readonly ILogger _logger;

    public MyClassTests(ITestOutputHelper output)
    {
        _output = output;
        _logger = output.BuildLogger();
    }

    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var sut = new MyClass(_logger);

        var actual = sut.DoSomething();

        // The xUnit test output should now include the log message from MyClass.DoSomething()

        actual.Should().NotBeNullOrWhiteSpace();
    }
}

This would output the following in the test results.

Information [0]: Hey, we did something

Support for ILogger<T> is there using the BuildLoggerFor<T> extension method.

using System;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;

public class MyClassTests
{
    private readonly ITestOutputHelper _output;
    private readonly ILogger<MyClass> _logger;

    public MyClassTests(ITestOutputHelper output)
    {
        _output = output;
        _logger = output.BuildLoggerFor<MyClass>();
    }

    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var sut = new MyClass(_logger);

        var actual = sut.DoSomething();

        // The xUnit test output should now include the log message from MyClass.DoSomething()

        actual.Should().NotBeNull();
    }
}

Inspection

Using this library makes it really easy to output log messages from your code as part of the test results. You may want to also inspect the log messages written as part of the test assertions as well.

The BuildLogger and BuildLoggerFor<T> extension methods support this by returning a ICacheLogger or ICacheLogger<T> respectively. The cache logger is a wrapper around the created logger and exposes all the log entries written by the test.

using System;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;

public class MyClassTests
{
    private readonly ITestOutputHelper _output;
    private readonly ICacheLogger _logger;

    public MyClassTests(ITestOutputHelper output)
    {
        _output = output;
        _logger = output.BuildLogger();
    }

    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var sut = new MyClass(_logger);

        sut.DoSomething();
        
        _logger.Count.Should().Be(1);
        _logger.Entries.Should().HaveCount(1);
        _logger.Last.Message.Should().Be("Hey, we did something");
    }
}

Perhaps you don't want to use the xUnit ITestOutputHelper but still want to use the ICacheLogger to run assertions over log messages written by the class under test. You can do this by creating a CacheLogger of CacheLogger<T> directly.

using System;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Xunit;

public class MyClassTests
{
    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var logger = new CacheLogger();

        var sut = new MyClass(_logger);

        sut.DoSomething();
        
        logger.Count.Should().Be(1);
        logger.Entries.Should().HaveCount(1);
        logger.Last.Message.Should().Be("Hey, we did something");
    }
}

Configured LoggerFactory

You may have an integration or acceptance test that requires additional configuration to the log providers on ILoggerFactory while also supporting the logging out to xUnit test results. You can do this by create a factory that is already configured with xUnit support.

using System;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Xunit;
using Xunit.Abstractions;

public class MyClassTests
{
    private readonly ILogger _logger;

    public MyClassTests(ITestOutputHelper output)
    {
        var factory = LogFactory.Create(output);

        // call factory.UseConsole or other provider extension method

        _logger = factory.CreateLogger(nameof(MyClassTests));
    }

    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var sut = new MyClass(_logger);

        // The xUnit test output should now include the log message from MyClass.DoSomething()

        var actual = sut.DoSomething();

        actual.Should().NotBeNullOrWhiteSpace();
    }
}

Existing Loggers

Already have an existing logger and want the above cache support? Got you covered there too using the WithCache() method.

using System;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;

public class MyClassTests
{
    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var logger = Substitute.For<ILogger>();

        logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true);

        var cacheLogger = logger.WithCache();

        var sut = new MyClass(cacheLogger);

        sut.DoSomething();

        cacheLogger.Count.Should().Be(1);
        cacheLogger.Entries.Should().HaveCount(1);
        cacheLogger.Last.Message.Should().Be("Hey, we did something");
    }
}

The WithCache() also supports ILogger<T>.

using System;
using Divergic.Logging.Xunit;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;

public class MyClassTests
{
    [Fact]
    public void DoSomethingReturnsValueTest()
    {
        var logger = Substitute.For<ILogger<MyClass>>();

        logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true);

        var cacheLogger = logger.WithCache();

        var sut = new MyClass(cacheLogger);

        sut.DoSomething();

        cacheLogger.Count.Should().Be(1);
        cacheLogger.Entries.Should().HaveCount(1);
        cacheLogger.Last.Message.Should().Be("Hey, we did something");
    }
}
Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48 net481
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Divergic.Logging.Xunit:

Package Downloads
AutoMoqFixture

Package Description

U2U.EntityFrameworkCore.Testing

Package Description

Reductech.Sequence.Core.TestHarness

Class library for automatically testing Sequence® Core steps.

Sequence.Core.TestHarness

Class library for automatically testing Sequence Core steps.

GitHub repositories (6)

Showing the top 5 popular GitHub repositories that depend on Divergic.Logging.Xunit:

Repository Stars
JasperFx/marten
.NET Transactional Document DB and Event Store on PostgreSQL
asynkron/protoactor-dotnet
Proto Actor - Ultra fast distributed actors for Go, C# and Java/Kotlin
imperugo/StackExchange.Redis.Extensions
sethreno/schemazen
Script and create SQL Server objects quickly
josephwoodward/GlobalExceptionHandlerDotNet
Exception handling as a convention in the ASP.NET Core request pipeline
Version Downloads Last updated
4.2.0 161,104 8/9/2022
4.2.0-beta0001 73 8/9/2022
4.1.0 64,146 6/23/2022
4.1.0-beta0002 73 6/23/2022
4.1.0-beta0001 76 6/22/2022
4.0.0 218,872 1/10/2022
3.6.1-beta0010 99 1/10/2022
3.6.0 831,091 11/13/2020
3.5.2-beta0019 230 11/13/2020
3.5.2-beta0018 225 11/13/2020
3.5.2-beta0017 218 11/13/2020
3.5.2-beta0016 221 11/13/2020
3.5.2-beta0015 264 11/12/2020
3.5.2-beta0010 240 11/12/2020
3.5.2-beta0006 266 11/10/2020
3.5.2-beta0003 634 10/14/2020
3.5.2-beta0001 8,298 10/12/2020
3.5.1 107,338 10/8/2020
3.5.1-releasejob0001 388 8/4/2020
3.5.1-beta0032 320 10/8/2020
3.5.1-beta0031 258 10/8/2020
3.5.1-beta0030 271 10/8/2020
3.5.1-beta0029 336 9/27/2020
3.5.1-beta0028 285 9/15/2020
3.5.1-beta0027 277 9/9/2020
3.5.1-beta0026 270 9/9/2020
3.5.1-beta0025 275 9/2/2020
3.5.1-beta0024 254 8/21/2020
3.5.1-beta0023 313 8/15/2020
3.5.1-beta0022 318 8/12/2020
3.5.1-beta0021 261 8/12/2020
3.5.1-beta0020 284 8/11/2020
3.5.1-beta0019 311 8/8/2020
3.5.1-beta0018 318 8/8/2020
3.5.1-beta0017 327 8/8/2020
3.5.1-beta0015 298 8/5/2020
3.5.1-beta0013 272 8/4/2020
3.5.1-beta0012 276 8/4/2020
3.5.1-beta0011 279 8/4/2020
3.5.1-beta0010 285 8/2/2020
3.5.1-beta0009 323 7/31/2020
3.5.1-beta0008 322 7/31/2020
3.5.1-beta0007 329 7/31/2020
3.5.1-beta0003 338 7/31/2020
3.5.0 141,894 6/22/2020
3.5.0-beta0001 295 6/17/2020
3.4.0 90,280 4/28/2020
3.3.1-beta0004 296 4/28/2020
3.3.0 54,927 3/18/2020
3.3.0-beta0005 388 3/18/2020
3.2.2-beta0003 2,669 1/12/2020
3.2.2-beta0002 362 1/12/2020
3.2.2-beta0001 353 1/12/2020
3.2.1 203,577 12/18/2019
3.2.1-beta0001 365 12/18/2019
3.2.0 505 12/18/2019
3.2.0-beta0002 375 12/18/2019
3.1.0 185,809 9/27/2019
3.1.0-beta0002 351 9/27/2019
3.0.0 63,678 5/3/2019
2.2.0 38,562 4/18/2019
2.2.0-beta0001 393 4/18/2019
2.1.0 1,613 4/14/2019
2.1.0-beta0003 405 4/14/2019
2.1.0-beta0002 378 4/13/2019
2.0.1-beta0001 434 3/25/2019
2.0.0 41,803 3/19/2019
1.1.0 47,214 6/3/2018
1.0.0 8,686 6/1/2018
0.2.0-beta0047 282 8/5/2020
0.2.0-beta0045 277 8/4/2020
0.2.0-beta0036 276 7/31/2020
0.2.0-beta0035 284 7/31/2020
0.2.0-beta0034 330 6/22/2020