如何在ASP.NET核心

如何在ASP.NET核心

问题描述:

与ILogger单元测试这是我的控制器:如何在ASP.NET核心

public class BlogController : Controller 
{ 
    private IDAO<Blog> _blogDAO; 
    private readonly ILogger<BlogController> _logger; 

    public BlogController(ILogger<BlogController> logger, IDAO<Blog> blogDAO) 
    { 
     this._blogDAO = blogDAO; 
     this._logger = logger; 
    } 
    public IActionResult Index() 
    { 
     var blogs = this._blogDAO.GetMany(); 
     this._logger.LogInformation("Index page say hello", new object[0]); 
     return View(blogs); 
    } 
} 

正如你可以看到我有2只依赖,一个IDAO和​​

这是我的测试类,我使用xUnit来测试和Moq创建模拟和存根,我可以嘲笑DAO容易,但与​​我不知道该怎么做,所以我只是传递null和注释掉调用登录控制器时运行测试。有没有办法测试,但仍然保持记录器?

public class BlogControllerTest 
{ 
    [Fact] 
    public void Index_ReturnAViewResult_WithAListOfBlog() 
    { 
     var mockRepo = new Mock<IDAO<Blog>>(); 
     mockRepo.Setup(repo => repo.GetMany(null)).Returns(GetListBlog()); 
     var controller = new BlogController(null,mockRepo.Object); 

     var result = controller.Index(); 

     var viewResult = Assert.IsType<ViewResult>(result); 
     var model = Assert.IsAssignableFrom<IEnumerable<Blog>>(viewResult.ViewData.Model); 
     Assert.Equal(2, model.Count()); 
    } 
} 

只是嘲笑它,以及其他任何依赖性:

var mock = new Mock<ILogger<BlogController>>(); 
ILogger<BlogController> logger = mock.Object; 

//or use this short equivalent 
logger = Mock.Of<ILogger<BlogController>>() 

var controller = new BlogController(logger); 

你可能需要安装Microsoft.Extensions.Logging.Abstractions包使用ILogger<T>

而且你可以创建一个真实的记录:

var serviceProvider = new ServiceCollection() 
    .AddLogging() 
    .BuildServiceProvider(); 

var factory = serviceProvider.GetService<ILoggerFactory>(); 

var logger = factory.CreateLogger<BlogController>(); 
+1

登录到调试输出窗口调用AddDebug()的工厂:工厂变种= serviceProvider.GetService ()AddDebug(); – spottedmahn

您可以使用一个模拟为存根,如伊利亚建议,如果你没有真正试图测试记录方法本身被调用。如果是这种情况,嘲笑记录器不起作用,你可以尝试几种不同的方法。

我写了一个short article显示了各种方法。该文章包括a full GitHub repo with each of the different options。最后,我的建议是使用自己的适配器,而不是直接使用ILogger类型,如果你需要能够测试它被调用。

https://ardalis.com/testing-logging-in-aspnet-core

其实,我发现Microsoft.Extensions.Logging.Abstractions.NullLogger <>它看起来像一个完美的解决方案。

+0

这似乎只适用于.NET Core 2.0,而不适用于.NET Core 1.1。 –

使用使用ITestOutputHelper(来自xunit)捕获输出和日志的自定义记录器。以下是仅将state写入输出的小样本。

public class XunitLogger<T> : ILogger<T>, IDisposable 
{ 
    private ITestOutputHelper _output; 

    public XunitLogger(ITestOutputHelper output) 
    { 
     _output = output; 
    } 
    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) 
    { 
     _output.WriteLine(state.ToString()); 
    } 

    public bool IsEnabled(LogLevel logLevel) 
    { 
     return true; 
    } 

    public IDisposable BeginScope<TState>(TState state) 
    { 
     return this; 
    } 

    public void Dispose() 
    { 
    } 
} 

用它在你的单元测试一样

public class BlogControllerTest 
{ 
    private XunitLogger<BlogController> _logger; 

    public BlogControllerTest(ITestOutputHelper output){ 
    _logger = new XunitLogger<BlogController>(output); 
    } 

    [Fact] 
    public void Index_ReturnAViewResult_WithAListOfBlog() 
    { 
    var mockRepo = new Mock<IDAO<Blog>>(); 
    mockRepo.Setup(repo => repo.GetMany(null)).Returns(GetListBlog()); 
    var controller = new BlogController(_logger,mockRepo.Object); 
    // rest 
    } 
}