2016-09-20 2 views
10

testen Ich möchte einige Protokolle protokolliert werden. Ich bin mit dem asp.net Kern eingebaute in ILogger und injizieren sie mit dem asp.net Kern integrierter DI:Wie asp.net Core integrierten Ilogger

private readonly ILogger<InvoiceApi> _logger; 

public InvoiceApi(ILogger<InvoiceApi> logger) 
{ 
    _logger = logger; 
} 

dann verwende ich es mag: _logger.LogError("error));

Ich versuchte, es zu verspotten (mit moq) wie üblich durch:

MockLogger = new Mock<ILogger<InvoiceApi>>(); 

und dies für den Test in den Dienst einzuspritzen:

new InvoiceApi(MockLogger.Object); 

dann Trie d überprüfen:

MockLogger.Verify(m => m.LogError(It.Is<string>(s => s.Contains("CreateInvoiceFailed")))); 

aber werfen:

ungültig auf einem nicht-virtuelles (overridable in VB) Mitglied überprüfen: m => m.LogError

So, wie kann Ich überprüfe diese Protokolle protokolliert?

+0

Bitte klären Sie Ihr spezielles Problem oder fügen Sie weitere Details genau zu markieren, was Sie brauchen. Wie es derzeit geschrieben wird, ist es schwer zu sagen, was genau Sie fragen. Informationen zur Klärung dieser Frage finden Sie auf der Seite [Wie Sie fragen] (http://stackoverflow.com/help/how-to-ask). – Nkosi

+0

Ich habe am Ende eine Zeile hinzugefügt. Ist jetzt die Frage klar? – arielorvits

+0

Sie zeigen nicht an, in welchem ​​Kontext Sie den Logger verwenden. Zeigen Sie das getestete System/die Methode an. Zeigen Sie, wie der Logger injiziert und verwendet wird. – Nkosi

Antwort

17

Wie @ Nkosi schon gesagt, können Sie nicht über eine Erweiterungsmethode spotten. Was Sie sollten Mock, ist the ILogger.Log method, die LogError calls into. Es macht den Bestätigungscode ein bisschen klobig, aber es sollte funktionieren:

MockLogger.Verify(
    m => m.Log(
     LogLevel.Error, 
     It.IsAny<EventId>(), 
     It.Is<FormattedLogValues>(v => v.ToString().Contains("CreateInvoiceFailed")), 
     It.IsAny<Exception>(), 
     It.IsAny<Func<object, Exception, string>>() 
    ) 
); 

(nicht sicher, ob dies kompiliert, aber Sie erhalten den Kern)

+1

Es tut! Das einzige Ding ist, It.IsAny () 'als vorletztes Argument hinzuzufügen. –

+0

Danke @khellang mit .Log anstelle von .LogError funktioniert! –

1

LogError ist eine Erweiterungsmethode (statisch) keine Instanzmethode. Sie können statische Methoden (daher Erweiterungsmethode) nicht "direkt" mit einem spöttischen Framework vortäuschen, daher kann Moq diese Methode nicht vortäuschen und somit verifizieren. Ich habe online Vorschläge zum Anpassen/Umhüllen des Ziel-Interfaces und zum Ausführen von Mocks gesehen, aber das würde bedeuten, dass es neu geschrieben wird, wenn Sie den Code ILogger an vielen Stellen im gesamten Code verwendet haben. Sie müssten 2 neue Typen erstellen, einen für die Wrapper-Klasse und den anderen für die mockbare Schnittstelle.

1

ich ein short article zeigt eine Vielzahl von Ansätzen geschrieben haben, einschließlich Spott über die zugrunde liegende Log() -Methode, wie in anderen Antworten hier beschrieben. Der Artikel enthält a full GitHub repo with each of the different options. Am Ende empfehle ich Ihnen, Ihren eigenen Adapter zu verwenden, anstatt direkt mit dem ILogger-Typ zu arbeiten, wenn Sie testen müssen, ob er aufgerufen wird.

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

Verwandte Themen