So as the title implies, this worked for us in .NET Core 2.2 and Moq Version 4.10.1. After upgrading to .NET Core 3.1 and Moq Version 4.14.5, the verify method is failing saying the method specified hasn't been called (no changes to the underlying code). I rolled back Moq to version 4.10.1 just to see if it was due to a change within the new version of Moq. I still get the same error.
Trying to verify that a log message has been written to the ILogger.
Weird thing is, if I debug the unit test and look at the mocked object with a variable watch, it shows that the method has indeed been invoked.
Relevant code:
public class AuditFilter, IResultFilter
{
...
public void OnResultExecuted( ResultExecutedContext context )
{
if( !IsContextValid( context ) )
{ return; }
...
}
public override bool IsContextValid( FilterContext context )
{
if( context == null )
{
Logger.Error( "Error writing to the audit log", new ArgumentNullException( nameof( context ) ) );
return false;
}
if( context.HttpContext == null )
{
Logger.LogError( "Error writing to the audit log", new ArgumentNullException( nameof( context.HttpContext ) ) );
return false;
}
return true;
}
public ILogger Logger { get; set; }
...
}
public class AuditTests : BaseTests
{
...
private Mock<ILogger> _mockLog;
private AuditFilter _filter;
[SetUp]
public void Setup()
{
_mockLog = new Mock<Microsoft.Extensions.Logging.ILogger>();
_mockLog.SetupAllProperties;
_filter = new AuditFilter();
}
[Test]
public void Service_Filters_Audit_IsContextValid_Context_Null()
{
var expected = false;
_filter.Logger = _mockLog.Object;
var actual = _filter.IsContextValid( null );
_mockLog.Verify( logger => logger.Log( LogLevel.Error,
It.IsAny<EventId>(),
It.IsAny<object>(),
It.IsAny<ArgumentNullException>(),
It.IsAny<Func<object, Exception, string>>() ),
Times.Once );
Assert.AreEqual( expected, actual );
}
...
}
Note: The method ILogger.LogError is a Microsoft extension method for ILogger that calls ILogger.Log method.
Below is the exception that is thrown.

Note: An integer implicitly casts to Microsoft.Extensions.Logging.EventId, the second input parameter type for the ILogger.Log method.
These signatures appear to match to me; so I'm not sure why it's saying it wasn't invoked.
To reiterate, this code worked prior to upgrading to .NET Core 3.1 and still works in our pre-forked code.
Also, before someone suggests that the method needs to be setup: it worked before the upgrade without it, and I already tried it and it didn't work.
