2009-07-30 11 views
6

Mock Ich probiere die MOQ Framework und bis jetzt habe ich eine Barriere getroffen. Der folgende Komponententest schlägt fehl, da der tatsächliche Wert der ViewName-Eigenschaft eine leere Zeichenfolge ist.Wie der Controller-Kontext mit Moq

Kann mir jemand bitte in die richtige Richtung weisen, warum dies nicht den Test besteht?

[TestMethod] 
public void Can_Navigate_To_About_Page() 
{ 
    var request = new Mock<HttpRequestBase>(); 
    request.Setup(r => r.HttpMethod).Returns("GET"); 
    var mockHttpContext = new Mock<HttpContextBase>(); 
    mockHttpContext.Setup(c => c.Request).Returns(request.Object); 

    var controllerContext = new ControllerContext(mockHttpContext.Object, 
           new RouteData(), 
           new Mock<ControllerBase>().Object); 
    var controller = new HomeController(); 

    controller.ControllerContext = controllerContext; 
    var result = controller.About() as ViewResult; 

    Assert.AreEqual("About", result.ViewName); 
} 

Das folgende ergibt auch einen leeren ViewName.

 HomeController controller = new HomeController(); 
     ViewResult result = controller.About() as ViewResult; 
     Assert.IsNotNull(result); 
     Assert.AreEqual("About", result.ViewName); 

Aus den Beispielen auf der Bahn, die ich gut TTD demons spöttisch und auch bin nur verwirrt, was andere Sanitär ich entweder die oben genannten ersten Einheit Testbeispiel Arbeit machen müssen.

Cheers,

Andrew

Antwort

7

Der Grund ist der Test versagt, denn was, wenn der View entscheidet Sie keine explizit angeben, in der Tiefen des Rahmens ist. Genauer gesagt in der View-Engine glaube ich. Um dies zu testen, müssten Sie viel mehr von der Request-Pipeline ausspionieren.

Was ich tue, und würde empfehlen, ist nicht auf die Standardeinstellungen verlassen und die Ansicht explizit angeben:

return View("About"); 

Dann wird der Wert dort sein, ohne zu prüfen, etwas spöttisch:

var controller = new HomeController(); 
var result = controller.About() as ViewResult; 
Assert.AreEqual("About", result.ViewName); 
+0

Vielen Dank, nachdem Sie eine der Methodensignaturen sehen (string viewName, Objektmodell), macht Ihr Punkt Sinn! Ps.s. der Test ist bestanden! :-) –

3

Das liegt daran, dass Sie Annahmen darüber machen, wie das MVC-Framework funktioniert. Wenn Sie sich auf die Konventionen verlassen, um die Ansicht zu finden, verlässt das Framework die ViewName-Eigenschaft tatsächlich als String.Empty, bis ExecuteResult() aufgerufen wird.

können Sie diesen Code siehe Linie 68 von ViewResultBase.ExecuteResult innerhalb the MVC source:

if (String.IsNullOrEmpty(ViewName)) { 
    ViewName = context.RouteData.GetRequiredString("action"); 
} 

Darüber hinaus sollten Sie vorsichtig sein, was Sie testen. Als Faustregel sollten Sie sich darauf konzentrieren, den Code zu testen, den Sie schreiben, nicht den Code des Framework. Das Testen, um sicherzustellen, dass der Ansichtsname per Konvention korrekt aufgelöst wird, ist wirklich ein Komponententest für das Framework selbst, keine Anwendung, die darauf aufgebaut ist.

Wenn Sie nach einer guten Möglichkeit suchen, in MVC Mocking zu betreiben, sollten Sie sich Ihre Routen testen lassen (was aussieht wie das, was Sie hier versuchen). Sie können find a post by Phil Haack concerning just this subject, um loszulegen.