This is my controller:
public class BlogController : Controller
{
private IDAO _blogDAO;
private readonly ILogger _
I've tried to mock that Logger interface using NSubstitute (and failed because Arg.Any<T>()
requeres a type parameter, which I can't provide), but ended up creating a test logger (similarly to @jehof's answer) in the following way:
internal sealed class TestLogger<T> : ILogger<T>, IDisposable
{
private readonly List<LoggedMessage> _messages = new List<LoggedMessage>();
public IReadOnlyList<LoggedMessage> Messages => _messages;
public void Dispose()
{
}
public IDisposable BeginScope<TState>(TState state)
{
return this;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var message = formatter(state, exception);
_messages.Add(new LoggedMessage(logLevel, eventId, exception, message));
}
public sealed class LoggedMessage
{
public LogLevel LogLevel { get; }
public EventId EventId { get; }
public Exception Exception { get; }
public string Message { get; }
public LoggedMessage(LogLevel logLevel, EventId eventId, Exception exception, string message)
{
LogLevel = logLevel;
EventId = eventId;
Exception = exception;
Message = message;
}
}
}
You can easily access all logged messages and assert all meaningful parameters provided with it.
Use Telerik Just Mock to create a mocked instance of the logger:
using Telerik.JustMock;
...
context = new XDbContext(Mock.Create<ILogger<XDbContext>>());