Mogger 1.0.1

dotnet add package Mogger --version 1.0.1
NuGet\Install-Package Mogger -Version 1.0.1
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="Mogger" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Mogger --version 1.0.1
#r "nuget: Mogger, 1.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Mogger as a Cake Addin
#addin nuget:?package=Mogger&version=1.0.1

// Install Mogger as a Cake Tool
#tool nuget:?package=Mogger&version=1.0.1

Mogger

NuGet

Mogger creates ILogger mocked instances that prints actual messages to the xUnit’s display output, with the ITestouOutputHelper abstraction.
Invoke the Create method to instantiate a new ILogger mock.

public class MyTests
{
    private readonly ITestOutputHelper _testOutputHelper;
    
    public MyTests(ITestOutputHelper testOutputHelper)
    {
        _testOutputHelper = testOutputHelper;
    }
    
    public void Method()
    {
        ILogger logger = Mogger.Create(_testOutputHelper);
        logger.LogInformation("Mogger's great");
    }
}

Log event messages will be printed to the display output, following the output template below
{Date:HH:mm:ss.fff} {Level, -5} [{ThreadId, -4}]: {Message}
{Exception.Type}: {Exception.Message}
{Exception.StackTrace}

The Create method returns an IMogger instance (or IMogger<>, in case of the Mogger<>.Create method), which has an ILogger property called Proxied. The Proxied property returns the actual mocked logger instance, which can be customized, if necessary.

The LogInformation, LogWarning , […] methods cannot be mocked (at least with FakeItEasy) because they are static extension methods of the ILogger interface. Trying to intercept them will cause an exception
FakeItEasy.Configuration.FakeConfigurationException:
The current proxy generator can not intercept the specified method for the following reason:
- Extension methods can not be intercepted since they're static.

Logging assertions

There are two methods to assert log events, MustHaveLogged and MustHaveNotLogged. Both methods have some overloads to specify which kind of event the assertion has to look for.

IMogger<MyService> logger = Mogger<MyService>.Create(_testOutputHelper);

// Asserts that one or more events have been raised.
logger.MustHaveLogged();

// Asserts that one or more events at the given level have been raised.
logger.MustHaveLogged(LogLevel.Information);

// Assers that one or more events that satisfies the predicate have been raised.
// 'args' is the ArgumentCollection of the invoked method.
logger.MustHaveLogged(args => args.Get<Exception>("exception") is ArgumentException);

// Asserts that no event has been raised.
logger.MustNotHaveLogged();

// Asserts that no event at the given level has been raised.
logger.MustNotHaveLogged(LogLevel.Information);

// Asserts that no event satisfying the predicate has been raised.
logger.MustNotHaveLogged(args => args.Get<Exception>("exception") is ArgumentException);

On top of that, use the AnyLogEvent, AnyLogEventAt and AnyLogEventThat extension methods to get a log event call representation to use the FakeItEasy API to it.

public static class MyMoggerExtensions
{
    public static void MustHaveLoggedThreeTimesExactly(this IMockLogger logger)
    {
        logger
            .AnyLogEvent()
            .MustHaveHappened(3, Times.Exactly);
    }
    
    public static void MustHaveLoggedAtInformationOnceOrMore(this IMockLogger logger)
    {
        logger
            .AnyLogEventAt(LogLevel.Information)
            .MustHaveHappened(1, Times.OrMore);
    }
    
    public static void MustNotHaveLoggedErrorWithNullException(this IMockLogger logger)
    {
        logger.AnyLogEventThat(args =>
        {
            var level = args.Get<LogLevel>("logLevel");
            var exception = args.Get<Exception>("exception");
                
            return
                level.Equals(LogLevel.Error) &&
                exception is null;
        })
        .MustNotHaveHappened();
    }
    
    public static void MustNotHaveLoggedEmptyMessage(this IMockLogger logger)
    {
        logger.AnyLogEventThat(args =>
        {
            var message = args.Get<object>("state")?.ToString();
            return string.IsNullOrEmpty(message);
        })
        .MustNotHaveHappened();
    }
}

Check the ILogger.Log method header to see what arguments the method has in order to implement your own log calls assertions.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1 226 4/4/2022
1.0.0 176 4/4/2022