Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

242
Views
¿Cómo verificar que se haya llamado al método de extensión ILogger<T>.Log usando Moq?

Creé un proyecto xUnit para probar este código de muestra

 public class ClassToTest { private readonly ILogger<ClassToTest> _logger; public ClassToTest(ILogger<ClassToTest> logger) { _logger = logger; } public void Foo() => _logger.LogError(string.Empty); }

Instalé Moq para crear una instancia simulada para el registrador

 public class ClassToTestTests { private readonly ClassToTest _classToTest; private readonly Mock<ILogger<ClassToTest>> _loggerMock; public ClassToTestTests() { _loggerMock = new Mock<ILogger<ClassToTest>>(); _classToTest = new ClassToTest(_loggerMock.Object); } [Fact] public void TestFoo() { _classToTest.Foo(); _loggerMock.Verify(logger => logger.LogError(It.IsAny<string>()), Times.Once); } }

Al ejecutar las pruebas me sale este mensaje de error

System.NotSupportedException: expresión no admitida: logger => logger.LogError(It.IsAny(), new[] { })

System.NotSupportedException Expresión no admitida: logger => logger.LogError(It.IsAny(), new[] { }) Los métodos de extensión (aquí: LoggerExtensions.LogError) no se pueden usar en expresiones de configuración/verificación.

Después de algunas investigaciones, sé que todos los métodos de registro son solo métodos de extensión. Moq no puede configurar métodos de extensión.

Me gustaría evitar la instalación de paquetes de terceros adicionales para este problema. ¿Hay alguna solución para pasar la prueba?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

No puedes burlarte de los métodos de extensión.

en lugar de burlarse

 logger.LogError(...)

Necesitas burlarte del método de interfaz.

 void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter);

LogError en realidad llama a ese método de interfaz así

 logger.Log(LogLevel.Error, 0, new FormattedLogValues(message, args), null, (state, ex) => state.ToString());

Así que tienes que burlarte

 _loggerMock.Verify(logger => logger.Log(It.Is(LogLevel.Error), It.Is(0), It.IsAny<FormattedLogValues>(), It.IsAny<Exception>(), It.IsAny<Func<TState, Exception, string>>()), Times.Once);

Descargo de responsabilidad No verifiqué el código

Editar después del comentario de pinkfloydx33, configuré un ejemplo de prueba en .net50 y llegué a la siguiente respuesta

Con el marco más reciente, la clase FormattedLogValues se ha hecho interna. Por lo tanto, no puede usar esto con los miembros genéricos de Moq.It. Pero Moq tiene una forma alternativa de hacer esto (esta respuesta también mencionó la solución)

Para una llamada al registrador como este

 _logger.LogError("myMessage");

Necesitas verificar así

 _loggerMock.Verify(logger => logger.Log( It.Is<LogLevel>(logLevel => logLevel == LogLevel.Error), It.Is<EventId>(eventId => eventId.Id == 0), It.Is<It.IsAnyType>((@object, @type) => @object.ToString() == "myMessage" && @type.Name == "FormattedLogValues"), It.IsAny<Exception>(), It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Once);

Utiliza It.IsAnyType para los tipos a los que no tiene acceso. Y si necesita restringir la verificación, puede agregar una función <objeto, tipo> para verificar si el tipo es el que espera o enviarlo a la interfaz pública y validar cualquier miembro público que tenga.

Cuando trabaja con un mensaje de cadena y algunos parámetros, debe convertir el objeto de tipo FormattedLogValues en la interfaz IReadOnlyList<KeyValuePair<string, object?>> y verificar la cadena o los valores de los diferentes parámetros.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!