NSubstitute.Community.Logging 0.0.1

dotnet add package NSubstitute.Community.Logging --version 0.0.1
NuGet\Install-Package NSubstitute.Community.Logging -Version 0.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="NSubstitute.Community.Logging" Version="0.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NSubstitute.Community.Logging --version 0.0.1
#r "nuget: NSubstitute.Community.Logging, 0.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 NSubstitute.Community.Logging as a Cake Addin
#addin nuget:?package=NSubstitute.Community.Logging&version=0.0.1

// Install NSubstitute.Community.Logging as a Cake Tool
#tool nuget:?package=NSubstitute.Community.Logging&version=0.0.1

Introduction

NSubstitute.Community.Logging is a collection of helper methods that make it easy to inject substitute loggers into an IServiceProvider and verify that specific logging activity occurred.

Getting Started

First install NSubstitute.Community.Logging into your test project from Nuget.

Substitute Logger

Just call .AddSubstituteLoggers() on your ServiceCollection before buiding it into an IServiceProvider to add ILoggerFactory, ILogger, and ILogger<T> generated using NSubstitute.

var serviceProvider = new ServiceCollection().AddSubstituteLoggers().BuildServiceProvider();

var mockLoggerFactory = serviceProvider.GetService<ILoggerFactory>();
var mockLogger = serviceProvider.GetService<ILogger>();
var mockLoggerT = serviceProvider.GetService<ILogger<MyClass>>();

Log Verification: Basic

NSubstitute.Community.Logging lets you easily assert that specific logging took place. All you need is any NSubstitute substitute ILogger. Then you can verify logs using syntax similar to how the application wrote them. See LoggerExtensionsTests for more examples.

Make sure specific LogInformation call occured

var Target = Substitute.For<ILogger>();
var exception = new KeyNotFoundException();
var message = "This is a {log} message";
var args = new object[] { "log" };
Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(Target, exception, message, args);

Target.Received(1)
    .LogInformation(exception, message, args);

Target.DidNotReceive()
    .LogInformation(exception, message);
Target.DidNotReceive()
    .LogInformation(message, args);
Target.DidNotReceive()
    .LogInformation(message);

Log Verification: Advanced

Sometimes you don't want to or can't match on every nuance of a log message. For these cases there is CallToLog which behaves like Arg.Is for any provided argument and behaves like Arg.Any for omitted arguments. This allows you to verify log events by:

  • log level
  • OriginalFormat
  • event Id
  • exception
  • any combination of the above in the same log!

NOTE: CallToLog methods work with any NSubstitute Recieved Calls

Make sure no warnings or errors were logged while the test was running

var Target = Substitute.For<ILogger>();
Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(Target, "I am an informational log.");

Target.DidNotReceive()
    .CallToLog(LogLevel.Warning);

Target.DidNotReceive()
    .CallToLog(LogLevel.Error);

Make sure a similar message was logged

var Target = Substitute.For<ILogger>();
Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(Target, "I am an informational log.");

Target.Received(1)
    .CallToLog(LogLevel.Information, "I am an informational log.");

Log Verification: Custom Logic

Somes you want to verify the value of arguments provided to a Log but cannot match all the arguments or cannot match the exact value that was used. See CallToLogPredicateTests for more examples.

Match the message and some arguments exactly

var Target = Substitute.For<ILogger>();
Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(Target, "{ErrorCode} There were {ErrorCount} errors that happened on {Where}.", Guid.NewGuid(), 13, "earth");

Target.Received(1)
    .CallToLog(LogLevel.Warning,
    _ => _.OriginalFormat.Equals("{ErrorCode} There were {ErrorCount} errors that happened on {Where}.")
        && _.KeyEquals("ErrorCount", 13)
        && _.KeyEquals("Where", "earth")
    );

Match the message and arguments more generally

var Target = Substitute.For<ILogger>();
var now = DateTime.Now;
Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(Target, "there were {oopies} things you might want to know about. {where} {when}", 13, "earth", now);
var planets = new[] { "mars", "earth" };

Target.Received(1)
    .CallToLog(LogLevel.Warning,
    _ => _.OriginalFormat.StartsWith("there were {oopies}")
        && _.TryGetValue("oopies", out int oopies) && oopies > 10
        && _.TryGetValue("where", out string where) && planets.Contains(where)
        && _.TryGetValue("when", out DateTime when) && when <= DateTime.Now
    );

More Examples

See the tests for more examples!!!

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 is compatible.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
0.0.1 2,292 9/15/2023