Home > Software design >  Difficulties mocking ILogger and verifying method calls
Difficulties mocking ILogger and verifying method calls

Time:12-20

I'm trying to test that one of my controller end points calls the LogError once. This is the test:

[Fact]
        public void Log_error_should_call_logger_error_method()
        {
            //Arrange
            var applicationException = new ApplicationException("This is a mocked exception");
            var exceptionHandlerFeatureMock = ErrorsControllerGenerator.GenerateExceptionHandlerFeatureMock(applicationException);
            Mock<ILogger<ErrorsController>> iLoggerMock = new Mock<ILogger<ErrorsController>>();
            var sut = ErrorsControllerGenerator.GenerateErrorsController(exceptionHandlerFeatureMock, iLoggerMock); 

            //Act
            sut.LogError("This is a test error");

            //Assert
            iLoggerMock.Verify(x => x.LogError("This is a test error"), Times.Once());
        }

I'm receiving the following error when running the test:

System.NotSupportedException : Invalid verify on a non-virtual (overridable in VB) member: x => x.LogError("This is a test error", new[] {  })

I'm slightly confused by this as from what I understand, this shouldn't happen because I'm mocking the interface rather than the concrete implementation? If I was to use the concrete logger class, I know that the method would have to be marked as virtual for this to work but I didn't think that was the case when using interfaces.

I've tried adding this line to the //Arrange part of the test:

iLoggerMock.Setup(x => x.LogError(It.IsAny<string>())).Verifiable();

But this just throws this error instead:

System.NotSupportedException : Expression references a method that does not belong to the mocked object: x => x.LogError(It.IsAny<String>(), new[] {  })

This also confuses me as the mocked object (ILogger) does have a LogError method

CodePudding user response:

You can't mock logger methods such as LogError because unfortunately they are extension methods and are not defined in the ILogger interface.

Instead of trying to verify whether the relevant log methods were called, perhaps you could verify the executed code takes the expected path i.e. the path where the relevant log methods would be called.

  • Related