using Microsoft.Extensions.Logging; using NSubstitute; using NSubstitute.Core; namespace Cleanuparr.Infrastructure.Tests.TestHelpers; /// /// Extension methods for verifying ILogger calls with NSubstitute. /// public static class LoggerVerificationExtensions { /// /// Asserts that the logger received exactly log calls /// at the given level whose message contains the specified text. /// public static void ReceivedLogContaining( this ILogger logger, LogLevel level, string message, int count = 1) { var matchingCalls = GetLogCalls(logger, level, message); if (matchingCalls.Count != count) { throw new Exception( $"Expected {count} log call(s) at {level} containing \"{message}\", " + $"but found {matchingCalls.Count}."); } } /// /// Asserts that the logger received at least one log call /// at the given level whose message contains the specified text. /// public static void ReceivedLogContainingAtLeastOnce( this ILogger logger, LogLevel level, string message) { var matchingCalls = GetLogCalls(logger, level, message); if (matchingCalls.Count == 0) { throw new Exception( $"Expected at least 1 log call at {level} containing \"{message}\", " + $"but found none."); } } /// /// Asserts that the logger did not receive any log calls /// at the given level whose message contains the specified text. /// public static void DidNotReceiveLogContaining( this ILogger logger, LogLevel level, string message) { var matchingCalls = GetLogCalls(logger, level, message); if (matchingCalls.Count > 0) { throw new Exception( $"Expected no log calls at {level} containing \"{message}\", " + $"but found {matchingCalls.Count}."); } } private static List GetLogCalls(ILogger logger, LogLevel level, string message) { return logger.ReceivedCalls() .Where(c => c.GetMethodInfo().Name == "Log") .Where(c => c.GetArguments().Length > 0 && c.GetArguments()[0] is LogLevel l && l == level) .Where(c => c.GetArguments().Length > 2 && c.GetArguments()[2]?.ToString()?.Contains(message) == true) .ToList(); } }