TState in ILogger.Log<TState> used to be object, now FormattedLogValues
See original GitHub issueProbably 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:
- Created 4 years ago
- Reactions:4
- Comments:13 (2 by maintainers)
Top GitHub Comments
@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:
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:Note the use of
It.IsAnyType
, which will act as a type wildcard and match the (now internal)FormattedLogValues
.