Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

246
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda