adrianiftode / Moq.ILogger

Easy verify ILogger Moq mocks
Apache License 2.0
66 stars 7 forks source link

VerifyLog() doesn't work when message comes from Resource file. #14

Open hguy opened 1 year ago

hguy commented 1 year ago

This doesn't work. Any idea ?

message : Could not deserialize input data for assessmentDetailId {Id}

In SUT

_logger.LogWarning(CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId, assessmentDetail.Id);

In TEST

_mockLogger.VerifyLog(l => l.LogWarning(CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId, It.IsAny<int>()), Times.Exactly(1));
hguy commented 1 year ago

I succeed doing something as follow, but it's not convenient.


// In TEST
_mockLogger.VerifyLog(l => l.LogWarning(It.Is<string>(msg => TestString(msg, assessmentDetailId)), assessmentDetailId), Times.Exactly(1));

// Helper
private static bool TestString(string mess, int assessmentDetailId)
{
      return mess == CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId.PatternReplace(new() { { "Id", assessmentDetailId.ToString() } });
}
adrianiftode commented 1 year ago

Could you post the value of CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId? What CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId does?

adrianiftode commented 1 year ago

I can confirm this is an issue with the following test. I will see what I can do

        public void Verify_a_message_with_method_call_that_returns_a_format_it_verifies()
        {
            var loggerMock = new Mock<ILogger<object>>();
            loggerMock.Object.LogInformation(GetMessageWithFormat(), 0);

            Action act = () => loggerMock.VerifyLog(c => c.LogInformation(GetMessageWithFormat(), It.IsAny<int>()));

            act.Should().NotThrow();
        }
        string GetMessageWithFormat() => "Test message {Id}";

With the following failure

   Did not expect any exception, but found Moq.VerifyLogException with message "
Expected invocation on the mock at least once, but was never performed: c => c.LogInformation(VerifyLogExtensionsTests.GetMessageWithFormat(), new[] { (object)It.IsAny<int>() })

"
     at Moq.VerifyLogExtensions.Verify[T](Mock`1 loggerMock, Expression`1 expression, Nullable`1 times, Func`1 timesFunc, String failMessage) in Moq.ILogger\VerifyLogExtensions.cs:line 447
     at Moq.VerifyLogExtensions.VerifyLog[T](Mock`1 loggerMock, Expression`1 expression) in Moq.ILogger\src\Moq.ILogger\VerifyLogExtensions.cs:line 259
     at Moq.Tests.VerifyLogExtensionsTests.<>c__DisplayClass35_0.<Verify_a_message_with_method_call_that_returns_a_format_it_verifies>b__0() in Moq.ILogger\tests\Moq.ILogger.Tests\VerifyLogExtensionsTests.cs:line 444
     at FluentAssertions.Specialized.DelegateAssertions`1.InvokeSubjectWithInterception() in C:\projects\fluentassertions-vf06b\Src\FluentAssertions\Specialized\DelegateAssertions.cs:line 256

.

hguy commented 1 year ago

Could you post the value of CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId? What CoreResource.LOG_CouldNotDeserializeInputDataForAssessmentDetailId does?

It's a standard string resource from a .RESX File