2010-12-13 3 views
0

Ich habe einen Controller namens NewsController, der Konstruktor dieses Controllers erhält einen INewsService als Parameter.Unit-Test, um zu prüfen, ob eine Aktionsmethode die Service-Schicht

Ich habe eine Methode in diesem Controller namens GetAllNews(), die ein JSON-Ergebnis zurückgibt, das ich zum Auffüllen einer YUI-Datentabelle verwenden. Ich möchte einen Komponententest schreiben, der prüft, ob die FindAll-Methode des Nachrichtendienstes aufgerufen wurde, um alle Nachrichten zurückzugeben. Wie würde ich das tun? Was ich zur Zeit habe, ist:

public JsonResult GetAllNews() 
{ 
    var items = newsService.FindAll(); 
    var jsonResult = Json(items); 

    return jsonResult; 
} 

My Unit-Test für die Steuerung wie folgt aussieht:

public NewsControllerTest() 
{ 
    newsServiceStub = MockRepository.GenerateStub<INewsService>(); 
    newsController = new NewsController(newsServiceStub); 
} 

[Test] 
public void GetAllNews_should_use_news_service() 
{ 
    // Arrange 
    List<News> newsList = new List<News>(); 
    newsServiceStub.Stub(s => s.FindAll()).Return(newsList); 

    // Act 
    var actual = newsController.GetAllNews(); 

    // Assert 
    newsServiceStub.VerifyAllExpectations(); 
} 

Der Test mit dem obigen Code übergibt. Aber wenn ich GetAllNews() ändern würde, um wie unten zu aussehen, dann übergibt es auch. Sollte es nicht scheitern? Was ich versuche, ist zu prüfen, ob GetAllNews(), um den Nachrichtendienst verwendet:

public JsonResult GetAllNews() 
{ 
    return null; 
} 
+0

Als eine Randnotiz, warum halten Sie dies für einen nützlichen Test? – bzlm

+0

@bzim: Ich bin ein Anfänger, immer noch lernen. Es ist mir nicht immer klar, was ich testen soll und was nicht. –

Antwort

3

Wenn Sie mit ihm weg bekommen können, nicht Unit-Test, dass eine bestimmte Methode aufgerufen wurde. Der Punkt der Komponententests besteht darin, das Verhalten zu testen, nicht die Implementierung. Testen, dass FindAll aufgerufen wird, testet eine Implementierung. Dies führt zu brüchigen Tests, die brechen, wenn Sie die Implementierung ändern, aber das Verhalten ändert sich nicht. Den Kunden ist es egal, wie sie ihnen alle Neuigkeiten bringen, sie wollen nur, dass sie ihnen alle Neuigkeiten bringen.

public void GetAllNews_should_use_news_service() 

sollte also

public void GetAllNews_should_get_all_the_news 

sein, und ich werde die Details der Codierung, dass bis zu Ihnen verlassen.

+0

Durch Verhalten meinst du? Was wäre das Verhalten meiner GetAllNews() -Methode? Wenn Sie den Test GetAllNews_should_get_all_the_news nennen, was würden Sie in den Testcode aufnehmen? Können Sie bitte einen Beispielcode in Ihrer Antwort oben angeben? –

1

Wie andere darauf hingewiesen haben, kann das Testen bestimmter Methodenaufrufe auf lange Sicht brüchig sein.

Aus der Sicht von Rhino.Mocks sollten Sie jedoch einen Mock anstelle eines Stubs verwenden, wenn Sie die Erwartungen überprüfen möchten. Ändern Sie GenerateStub zu einem GenerateMock und Ihren .Stub() Anruf an einen .Expect() Anruf. Das sollte deinen Test beheben.

+0

Was ist der Unterschied zwischen Mock und Stub? Wann verwende ich die beiden? –

+0

Stubs werden für vordefinierte Antworten verwendet. Mocks werden verwendet, um die Erwartungen zu überprüfen. Sie können Mocks verwenden, um vordefinierte Antworten bereitzustellen, aber Stubs protokollieren Methodenaufrufe nicht und können daher nicht zur Validierung von Erwartungen verwendet werden. – PatrickSteele

1

Sie könnten diesen Artikel von Martin Fowler interessant auf die Unterschiede zwischen Mocks und Stubs finden.

http://www.martinfowler.com/articles/mocksArentStubs.html

Fowler Punkte Stummel aus verwendet werden, für Zustand Überprüfung während Mocks für Verhalten Überprüfung verwendet werden.

Verwandte Themen