У меня есть трудные времена с NSubstitute, чтобы проверить, был ли вызван метод ILogger.LogCritical(...)
.
Например, с кодом ниже:
[Fact]
public void TestNSubstituteAgain()
{
var logger = Substitute.For<ILogger<StockService>>();
logger.LogCritical(new Exception(), "Hey lads!");
logger.Received().Log(
LogLevel.Critical,
Arg.Any<EventId>(),
Arg.Any<object>(),
Arg.Any<Exception>(),
Arg.Any<Func<object, Exception, string>>()
);
}
Я получаю это исключение:
Rm.Combo.App.Tests.VirtualParcels.Services.StockServiceTest.TestNSubstituteAgain
NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:
Log<Object>(Critical, any EventId, any Object, any Exception, any Func<Object, Exception, String>)
Actually received no matching calls.
at NSubstitute.Core.ReceivedCallsExceptionThrower.Throw(ICallSpecification callSpecification, IEnumerable`1 matchingCalls, IEnumerable`1 nonMatchingCalls, Quantity requiredQuantity)
at NSubstitute.Routing.Handlers.CheckReceivedCallsHandler.Handle(ICall call)
at NSubstitute.Routing.Route.Handle(ICall call)
at NSubstitute.Core.CallRouter.Route(ICall call)
at NSubstitute.Proxies.CastleDynamicProxy.CastleForwardingInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at NSubstitute.Proxies.CastleDynamicProxy.ProxyIdInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.ObjectProxy_2.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
at Rm.Combo.App.Tests.VirtualParcels.Services.StockServiceTest.TestNSubstituteAgain() in C:\Users\eperret\Desktop\combo\api\Rm.Combo.App.Tests\VirtualParcels\Services\StockServiceTest.cs:line 99
// 1] Ok the call I am making is that ext. method below:
public static void LogCritical(this ILogger logger, Exception exception, string message, params object[] args)
{
logger.Log(LogLevel.Critical, exception, message, args);
}
// 2] Which forwards to that other ext. method below:
public static void Log(this ILogger logger, LogLevel logLevel, Exception exception, string message, params object[] args)
{
logger.Log(logLevel, 0, exception, message, args);
}
// 3] and... then here (still an ext. method tho):
public static void Log(this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string message, params object[] args)
{
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
logger.Log(logLevel, eventId, new FormattedLogValues(message, args), exception, _messageFormatter);
}
// 4] to finally end up with this "direct" interface method:
void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter);
// Note: which is supposedly what I am gonna ask NSubstitute to check against, right? (since we cannot use NSubstitute `Received` method on ext. method, it has to be the corresponding instance method)
Примечание: FormattedLogValues
- это internal struct
, поэтому мне действительно пришлось использовать Arg.Any<object>
.
Когда я проверяю фактически принятые вызовы, я вижу, чтоУ логгера есть вызов, и я не слишком уверен, насколько он отличается от того, против которого я утверждаю. Как будто я ставлю точку останова на что-то вроде var re = logger.ReceivedCalls();
во время отладки моего модульного теста:
Я действительно не знаю, что не считаетсяправильные параметры утверждения NS Received()
.
Есть мысли?