2009-07-30 151 views
6

我正在嘗試MOQ框架,現在我已經遇到了障礙。以下單元測試失敗,因爲ViewName屬性的實際值是空字符串。如何用moq模擬控制器上下文

任何人都可以指出我在正確的方向,請問爲什麼這不通過測試?

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

以下也會產生一個空的ViewName。

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

從中演示了嘲諷網絡以及良好的TTD上的例子,我只是困惑,我需要什麼其他的管道,使上述任一第一單元測試例的工作。

乾杯,

安德魯

回答

7

究其原因,測試失敗是因爲什麼決定VIEWNAME當你不指定一個明確是在框架的深處。更確切地說,在視圖引擎中我相信。所以爲了測試它,你將不得不嘲笑更多的請求管道。

我做什麼,並建議,是不依賴於默認值,並指定明確的觀點:

return View("About"); 

則該值將在那裏沒有嘲笑任何測試:

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

Thankyou在看到方法簽名之一是View(字符串viewName,對象模型)後,您的觀點變得非常有意義!附:測試通過了! :-) – 2009-07-30 14:41:06

3

這是因爲你正在假設MVC框架是如何工作的。如果您依賴約定來查找視圖,則框架實際上將ViewName屬性保留爲String.Empty,直到調用ExecuteResult()

你可以看到的ViewResultBase.ExecuteResult 68行的代碼中the MVC source

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

此外,你應該小心你正在測試什麼。作爲一個經驗法則,您應該專注於測試您編寫的代碼,而不是框架的代碼。測試以確保正確解析視圖名稱是對框架本身的單元測試,而不是構建在其上的應用程序。

如果你正在尋找一種在MVC中使用模擬的好方法,你可能需要考慮測試你的路由(看起來像你在這裏試圖做的那種)。你可以find a post by Phil Haack concerning just this subject讓你開始。