2017-04-15 27 views
22

में 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 और एक ILogger

है और यह अपने परीक्षण वर्ग है , मैं xUnit का परीक्षण और मॉक बनाने के लिए मॉक और स्टब बनाने के लिए उपयोग करता हूं, मैं DAO को मॉक कर सकता हूं, लेकिन ILogger के साथ मुझे नहीं पता कि मुझे क्या करना है, इसलिए मैं सिर्फ शून्य को पास करता हूं और परीक्षण चलाने पर नियंत्रक में लॉग इन करने के लिए कॉल को टिप्पणी करता हूं। क्या परीक्षण करने का कोई तरीका है लेकिन फिर भी लॉगजर को किसी भी तरह रखना है?

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

उत्तर

26

बस किसी भी अन्य निर्भरता के रूप में रूप में अच्छी तरह यह नकली:

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

आप शायद ILogger<T> उपयोग करने के लिए Microsoft.Extensions.Logging.Abstractions पैकेज स्थापित करने की आवश्यकता होगी।

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

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

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

की तरह अपने unittests में यह प्रयोग करें:। वर कारखाने = serviceProvider.GetService () AddDebug(); – spottedmahn

4

आप एक नकली एक ठूंठ के रूप में, के रूप में इल्या पता चलता है, अगर आप वास्तव में परीक्षण करने के लिए है कि प्रवेश विधि ही बुलाया गया था कोशिश नहीं कर रहे उपयोग कर सकते हैं:

इसके अलावा आप एक असली लकड़हारा बना सकते हैं। यदि ऐसा है, तो लॉगर का मज़ाक उड़ाता नहीं है, और आप कुछ अलग दृष्टिकोणों को आजमा सकते हैं।

मैंने short article लिखा है जो विभिन्न दृष्टिकोण दिखा रहा है। लेख में a full GitHub repo with each of the different options शामिल है। अंत में, मेरी सिफारिश है कि आप सीधे आईएलओगर प्रकार के साथ काम करने के बजाय अपने एडाप्टर का उपयोग करें, अगर आपको यह जांचने में सक्षम होना चाहिए कि इसे कॉल किया जा रहा है।

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

6

वास्तव में, मैं Microsoft.Extensions.Logging.Abstractions.NullLogger < पाया है> जो एक सटीक समाधान की तरह दिखता है।

+0

यह केवल .NET कोर 2.0 के लिए काम करता है, न कि .NET कोर 1.1। –

2

आउटपुट और लॉग कैप्चर करने के लिए 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() 
    { 
    } 
} 

() कारखाने पर डिबग आउटपुट विंडो कॉल AddDebug को लॉग इन करने के

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