Net core and NUnit test case. I have my controller as below.
public class MyController : ControllerBase
{
public MyController(ILogger<MyController > logger)
{
this.Logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
private readonly ILogger<MyController > Logger;
public async Task<ActionResult> GetList()
{
this.Logger.LogInformation($"MyList: Some results came");
}
}
Then below my unit test case.
public class MyControllerTests
{
private Mock<ILogger<MyController>> Logger = new Mock<ILogger<MyController>>();
internal MyController myController;
public MyControllerTests()
{
this.myController= new MyController(this.Logger.Object);
}
[Test]
public async Task ListTest()
{
Logger.Verify(
x => x.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => string.Equals("MyList: Some results came", o.ToString(), StringComparison.InvariantCultureIgnoreCase)),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
//rest of the code but i am getting error in above line
}
}
Above code gives error
Moq.MockException : ILogger.Log(LogLevel.Information, 0, ListTest : Successfully Fetched the Results, null, Func<FormattedLogValues, Exception, string>) invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.
Can someone help me to fix this. Any help would be greatly appreciated. Thanks
You're very close. Here's an article about this. Here are the two working verification's I've come up with:
_logTest.Process();
_loggerMock.Verify(l => l.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(),
It.IsAny<Exception>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Exactly(1));
This version allows you to get more specific:
_loggerMock.Verify
(
l => l.Log
(
//Check the severity level
LogLevel.Error,
//This may or may not be relevant to your scenario
It.IsAny<EventId>(),
//This is the magical Moq code that exposes internal log processing from the extension methods
It.Is<It.IsAnyType>((state, t) =>
//This confirms that the correct log message was sent to the logger. {OriginalFormat} should match the value passed to the logger
//Note: messages should be retrieved from a service that will probably store the strings in a resource file
CheckValue(state, "MyList: Some results came", "{OriginalFormat}") &&
//This confirms that an argument with a key of "recordId" was sent with the correct value
//In Application Insights, this will turn up in Custom Dimensions
CheckValue(state, recordId, nameof(recordId))
),
//Confirm the exception type
It.IsAny<ArgumentNullException>(),
//Accept any valid Func here. The Func is specified by the extension methods
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
//Make sure the message was logged the correct number of times
Times.Exactly(1)
);