dinsdag 11 oktober 2016

Simply check logged messages in .NET Core and Moq

The Microsoft.Extensions.Logging framework in ASP.NET Core is very useful for logging, but it can be somewhat verbose to check logged messages in your unit tests. Because the methods you use for logging (LogInformation, LogWarning etc.) are all extension methods, you cannot verify calls on them. You can verify calls to the Log method. But it took me some time to find out what the exact check should be. So I wrapped that knowledge into a utility method VerifyLog, in this Gist:
using Microsoft.Extensions.Logging;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Knaap.Utilties
{
public class SimpleLogCheck
{
[Fact]
public void TestLog()
{
var loggerMock = LoggerUtils.LoggerMock<SimpleLogCheck>();
loggerMock.Object.LogInformation("test");
loggerMock.VerifyLog(LogLevel.Information, "test");
}
}
public static class LoggerUtils
{
public static Mock<ILogger<T>> LoggerMock<T>() where T : class
{
return new Mock<ILogger<T>>();
}
/// <summary>
/// Returns an <pre>ILogger<T></pre> as used by the Microsoft.Logging framework.
/// You can use this for constructors that require an ILogger parameter.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static ILogger<T> Logger<T>() where T : class
{
return LoggerMock<T>().Object;
}
public static void VerifyLog<T>(this Mock<ILogger<T>> loggerMock, LogLevel level, string message, string failMessage = null)
{
loggerMock.VerifyLog(level, message, Times.Once(), failMessage);
}
public static void VerifyLog<T>(this Mock<ILogger<T>> loggerMock, LogLevel level, string message, Times times, string failMessage = null)
{
loggerMock.Verify(l => l.Log<Object>(level, It.IsAny<EventId>(), It.Is<Object>(o => o.ToString() == message), null, It.IsAny<Func<Object, Exception, String>>()), times, failMessage);
}
}
}
Happy logging!

Geen opmerkingen: