Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test asp.net core built-in Ilogger

I want to verify some logs logged. I am using the asp.net core built-in ILogger, and inject it with the asp.net core built-in DI:

private readonly ILogger<InvoiceApi> _logger;  public InvoiceApi(ILogger<InvoiceApi> logger) {     _logger = logger; } 

then I use it like: _logger.LogError("error));

I tried to mock it (with moq) as usual by:

MockLogger = new Mock<ILogger<InvoiceApi>>(); 

and inject this in the service for test by:

new InvoiceApi(MockLogger.Object); 

then tried verify:

MockLogger.Verify(m => m.LogError(It.Is<string>(s => s.Contains("CreateInvoiceFailed")))); 

but it throw:

Invalid verify on a non-virtual (overridable in VB) member: m => m.LogError

So, how can I verify this logs logged?

like image 344
arielorvits Avatar asked Sep 20 '16 21:09

arielorvits


People also ask

How do you mock an ILogger?

To mock an ILogger<T> object, we can use Moq library to instantiate a new Mock<ILogger<T>>() object. Make sure you have installed the latest Moq package (v4. 15.1 as of Nov. 16, 2020, which contains an update to support “nested” type matchers).


1 Answers

As @Nkosi've already said, you can't mock an extension method. What you should mock, is the ILogger.Log method, which LogError calls into. It makes the verification code a bit clunky, but it should work:

MockLogger.Verify(     m => m.Log(         LogLevel.Error,         It.IsAny<EventId>(),         It.Is<FormattedLogValues>(v => v.ToString().Contains("CreateInvoiceFailed")),         It.IsAny<Exception>(),         It.IsAny<Func<object, Exception, string>>()     ) ); 

(Not sure if this compiles, but you get the gist)

like image 80
khellang Avatar answered Oct 08 '22 21:10

khellang