2015-06-30 5 views
6

Es kann getestet werden, ob eine Methode mit Moq and dependency injection aufgerufen wurde. Ist es jedoch möglich, zu testen, ob eine Methode in einer Klasse eine andere in derselben Klasse aufruft?Test, ob Methode in ClassA von einer anderen Methode in ClassA aufgerufen wurde

Zum Beispiel möchte ich testen, dass, wenn ich eine bestimmte Ausnahme protokollieren, dass eine Informationsnachricht auch protokolliert wird.

Die Methode ist:

public void Error(string message, Exception exception, long logId = 0) 
{ 
    var int32 = (int)logId; 
    Info("Id was converted to an int so that it would fit in the log: " + logId, int32); 
    Error(message, exception, int32); 
} 

Dies war bei Einheit mein Versuch, es zu testen. Der Test schlägt fehl, gibt es einen Weg, wie es gemacht werden kann?

void logging_an_error_with_a_long_id_also_logs_info() 
{ 
    var mock = new Mock<ILogger>(); 
    var testedClass = new Logger(); 
    var counter = 0; 

    testedClass.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue); 

    mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>())); 
} 

Da die Info und Error Methoden in der gleichen Klasse (Klasse A) sind, ich glaube nicht, dass ich KlasseA als Abhängigkeit in KlasseA passieren kann. Muss es nicht getestet werden?

+0

Schauen Sie [hier] (http://stackoverflow.com/questions/1417048/how-to-verify-another-method-in-the-class-was-called-using-moq). – dee

Antwort

7

Das Beste, was Sie tun können, ist Infovirtual. Auf diese Weise können Sie eine Mock<Logger> erstellen, CallBase = true festlegen und überprüfen, dass Info aufgerufen wurde.

var mock = new Mock<Logger> 
{ 
    CallBase = true 
}; 

mock.Object.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue); 

mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>())); 

Auf diese Weise sind Sie immer noch die tatsächliche Umsetzung von Error Aufruf, aber Sie haben verwendet Moq die Info Methode zur Überprüfung aufgerufen wurde.

+0

+1 das funktioniert, wenn Mock verwendet wird, weil die echte Klasse benötigt wird. Funktioniert nicht für Schnittstelle Mock . – dee

5

Es fühlt sich an, als ob Sie versuchen, das Falsche zu testen. Es ist nicht wirklich wichtig, dass die Info-Methode für Ihre Klasse von der Error-Methode aufgerufen wird. Wichtig ist, dass das Verhalten der Info-Methode auftritt. Wie es passiert, ist ein Implementierungsdetail der Klasse.

Wenn ich ein Mathe-Klasse mit zwei Funktionen hatte:

public int Mult(int x, int y) { 
    return x*y; 
} 

public int Sqr(int x) { 
    return Mult(x,y); 
} 

würde ich nicht auf die Mult Funktion rief Aufruf Sqr testen, würde ich Sqr(4)==16 testen. Es spielt keine Rolle, ob diese Berechnung in der Sqr-Methode oder in einer anderen Methode der Klasse stattfindet.

Während @ Andrew's solution ist wahrscheinlich, was Sie wollen, spöttelt die Klasse, die Sie testen, zu eng gekoppelten, brüchigen Tests führen.

Wenn es unpraktisch ist, den Aufruf zu testen, indem man seine Nebenwirkungen beobachtet, dann kann es ein Zeichen sein, dass die Implementierung ein bisschen Refactoring verwenden könnte.

+0

Es ist leichter zu sagen, es gibt wahrscheinlich einen besseren Weg, als einen besseren Weg zu bieten. – Hoppe

+0

@Hoppe Obwohl das stimmt, braucht man für einen besseren Weg oft mehr Kontext als vorgesehen ist (zum Beispiel habe ich keine Ahnung was den Inhalt deines Fehler oder Info Methoden ist). Manchmal ist das Beste, was man tun kann, eine alternative Richtung anzugeben, die in einigen Fällen eine Tür öffnet, die es ihnen erlaubt, ihr Problem anders zu betrachten. – forsvarir

Verwandte Themen