2017-04-15 15 views
22

To jest mój kontroler:Jak testów jednostkowych z ILogger w ASP.NET podstawowej

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); 
    } 
} 

Jak widać mam 2 zależności, a IDAO i ILogger

A to moja klasa Test , Używam xUnit do testowania, a Moq do tworzenia makiety i kodu pośredniczącego. Mogę łatwo kpić z DAO, ale z ILogger nie wiem, co robić, po prostu przekazuję null i komentuję połączenie, aby zalogować się do kontrolera po uruchomieniu testu. Czy istnieje sposób na sprawdzenie, ale nadal trzymasz rejestrator?

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()); 
    } 
} 

Odpowiedz

26

Wystarczy mock go jak każdego innego uzależnienia:

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); 

Prawdopodobnie trzeba będzie zainstalować pakiet do wykorzystania Microsoft.Extensions.Logging.AbstractionsILogger<T>.

Ponadto można tworzyć prawdziwe Rejestrator:

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

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

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

zalogować do AddDebug okno wyjściowe debugowania połączenia() w fabryce. Fabryka var = serviceProvider.GetService () AddDebug(); – spottedmahn

4

Można użyć makiety jako zalążek, jak sugeruje Ilya, jeśli nie jesteś rzeczywiście próbuje przetestować że sama metoda rejestrowania została wywołana. Jeśli tak jest, kpiny z rejestratora nie działają i możesz wypróbować kilka różnych podejść.

Napisałem short article przedstawiający różne podejścia. Artykuł zawiera a full GitHub repo with each of the different options. Ostatecznie zalecam używanie własnego adaptera zamiast pracy bezpośrednio z typem ILogger, jeśli musisz mieć możliwość przetestowania jego wywoływania.

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

6

Właściwie znalazłem Microsoft.Extensions.Logging.Abstractions.NullLogger <> który wygląda idealne rozwiązanie.

+0

To wydaje się działać tylko dla .NET Core 2.0, a nie .NET Core 1.1. –

2

Użyj niestandardowego programu rejestrującego, który używa ITestOutputHelper (z xunit) do przechwytywania danych wyjściowych i dzienników. Poniżej znajduje się mała próbka, która zapisuje tylko state na wyjściu.

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() 
    { 
    } 
} 

używać go w unittests jak

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 
    } 
} 
Powiązane problemy