问题
I have a .Net core 2.1 project that was using the Microsoft.Extensions.Logging.Internal
namespace, specifically FormattedLogValues
class.
I am now migrating to .Net core 3, I couldn't find a piece of documentation about where to FormattedLogValues
was moved or what is its replacement.
Even the namespace documentation is removed
Any tips?
回答1:
I fixed the problem by updating moq
to "4.13.1" and taking advantage of It.IsAnyType
.
_logger.Verify(f => f.Log(
It.IsAny<LogLevel>(),
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>) It.IsAny<object>()));
回答2:
This really depends on what you are doing with the type, but looking at the code in the github source it looks like the type still exists, but is internal - which means tht only the library itself can actually access the type, unless you've got the assembly InternalsVisibleTo("")
- but we'll ignore that for now.
So the type itself in is an implementation of IReadOnlyList<KeyValuePair<string, object>>
which is a bit of a weird one but means that if you are testing values going into the logger you can access then like so:
logger.State[0][0].Value
"State" here is what is defined in the library so the terminology is hopefully familiar.
If you are using Moq or equivilent, you could probably use:
_logger.Verify(f => f.Log(
It.IsAny<LogLevel>(),
It.IsAny<EventId>(),
It.IsAny<IReadOnlyList<KeyValuePair<string, object>>>(),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>) It.IsAny<object>()));
If you want to use it in your own logger you would have to create your own class that inherits from the class:
public class MyLogValues : IReadOnlyList<KeyValuePair<string, object>> {}
Then both classes can be reduced down to the interface
Hopefully this helps, I think it depends on what exactly you are using the type for.
回答3:
As previous answers pointed out, you must use It.IsAnyType
or It.IsValueType
.
So setup would look like this:
mock.Setup(_ => _.Log(
It.IsNotNull<LogLevel>(),
It.IsNotNull<EventId>(),
It.IsAny<It.IsValueType>(),
It.IsNotNull<Exception>(),
(Func<It.IsValueType, Exception, string>)It.IsAny<object>());
Ps. DO NOT forget to cast the last parameter.
If you also need to check parameters passed to the method you must use InvocationAction
:
mock.Callback(new InvocationAction((invocation) => {
Assert.AreEqual(level, invocation.Arguments[0]);
Assert.AreEqual(exception, invocation.Arguments[3]);
}));
来源:https://stackoverflow.com/questions/58500412/net-core-3-the-namespace-internal-does-not-exist-in-microsoft-extensions-loggi