question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TState in ILogger.Log<TState> used to be object, now FormattedLogValues

See original GitHub issue

Probably not a bug per se, so perhaps just to clarify my understanding of why this change happened, and to explain how this change is breaking us.

In 2.2 I have an assert that verify my code would log in a specific scenario using Moq:

_loggerMock.Verify(x => x.Log(LogLevel.Warning, It.IsAny<EventId>(), It.IsAny<object>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>())));

If I substitute object here with FormattedLogValues (which I can do in 2.2 because it’s a public class), Moq throws an exception and tells me that the actual invocation was with TState as object.

When I switch to 3.0 preview, the above Verify() call no longer works and Moq throws the same exception, except now showing that the actual invocation was with TState as FormattedLogValues. Unfortunately this class has now become an internal struct, and I cannot substitute it in place of object in my assert to get my tests working again, e.g. I cannot write

_loggerMock.Verify(x => x.Log(LogLevel.Warning, It.IsAny<EventId>(), It.IsAny<FormattedLogValues>(), It.IsAny<Exception>(), It.IsAny<Func<FormattedLogValues, Exception, string>>()));

What would be a way around this? This is breaking a lot of unit tests for us. Can FormattedLogValues be changed back to be public perhaps? I assume that when you use the simple extension methods like LogWarning(), this is the TState object that it uses, as opposed to me using the ILogger.Log() directly and providing my own state object. Except that this would involve so much change of existing code.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

19reactions
stakxcommented, Oct 8, 2019

@davidmilligan - My apologies, I think I made a mistake with the last parameter. As per https://github.com/moq/moq4/issues/918#issuecomment-527647423, Moq doesn’t support “nested” type matchers just yet, so for now you may be more lucky with:

-_loggerMock.Verify(x => x.Log(LogLevel.Warning, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>())));
+_loggerMock.Verify(x => x.Log(LogLevel.Warning, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), (Func<It.IsAnyType, Exception, string>)It.IsAny<object>()))));
7reactions
stakxcommented, Aug 31, 2019

It looks like Moq should support […]

FYI to anyone interested, Moq 4.13 (to be released shortly) will have support for generic type parameter matching. The above Verify can be written as:

_loggerMock.Verify(x => x.Log(LogLevel.Warning, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), It.IsAny<Func<object, Exception, string>>())));

Note the use of It.IsAnyType, which will act as a type wildcard and match the (now internal) FormattedLogValues.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do you mock ILogger LogInformation
IsAnyType is necessary because FormattedLogValues is now internal . Reference: TState in ILogger.Log used to be object, now FormattedLogValues.
Read more >
FormattedLogValues Class (Microsoft.Extensions.Logging. ...
A collection of log values formatted with options supported by Format. This type also enables using {NamedformatItem} in the format string.
Read more >
Mocking ILogger with Moq - Adam Storr
Now the interface defines a TState which can be anything, however the underlying "state" which the ILogger uses is the FormattedLogValues ...
Read more >
Checking matching and non matching arguments on ILogger
EventId is always 0; TState corresponds to new FormattedLogValues(message, args) and it's an object , in other words it's the formatted message ...
Read more >
ILogger.Log<TState> Method (Microsoft.Extensions.Logging)
Writes a log entry.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found