2010-10-02 36 views
0

我想單元測試自定義模型聯編程序 - 具體來說,我想了解它如何響應請求中提交的各種(可能有衝突的)值.Form和Request.QueryString集合 - 也就是說,如果我在查詢字符串中提交一個值並且在查詢字符串中提交另一個值(是的,是的,我知道這是邪惡的,但我希望測試覆蓋率以防萬一發生)我可以驗證哪一個將被綁定到模型上。在ASP.NET MVC中針對HTTP上下文測試自定義ModelBinder(1.0)

爲了做到這一點,我想模擬/僞造HTTP上下文,然後調用模型聯編程序並查看實際返回的內容。我見過幾篇關於測試ModelBinders的文章,但他們都使用自定義的ValueProvider,而我真的想測試MVC與Form/Request集合交互的方式。

任何想法我可以模擬這些集合,然後使我的模型聯編程序在我的單元測試中使用基於這個模擬HTTP上下文的'默認'ValueProvider?這是在ASP.NET MVC 1.0上。謝謝。

回答

0

釘它 - 該解決方案是嘲笑ControllerContext,然後建立一個新的System.Web.Mvc.ValueProviderDictionary並通過您的嘲笑控制器上下文到構造,如下所示:

[Test] 
public void WorkFolder_Id_Is_Parsed_From_QueryString() { 

    var fakeControllerContext = GetControllerContext(null, "folder=10"); 

    var bindingContext = new ModelBindingContext() { 
     ValueProvider = new System.Web.Mvc.ValueProviderDictionary(fakeControllerContext), 
     ModelName = "menu", 
     FallbackToEmptyPrefix = true 

    }; 
    var binder = new RenewalMenuPostModelBinder(); 
    var model = binder.BindModel(fakeControllerContext, bindingContext) as RenewalMenuPostModel; 
    Assert.That(model is RenewalMenuPostModel); 
    Assert.That(model.WorkFolderId.HasValue); 
    Assert.That(model.WorkFolderId.Value == 10); 

} 



private static ControllerContext GetControllerContext(NameValueCollection form, string queryString) { 
    Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>(); 
    mockRequest.Expect(r => r.Form).Returns(form); 

    var queryStringCollection = HttpUtility.ParseQueryString(queryString); 
    mockRequest.Expect(r => r.QueryString).Returns(queryStringCollection); 

    Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>(); 
    mockHttpContext.Expect(c => c.Request).Returns(mockRequest.Object); 

    return new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock<ControllerBase>().Object); 
}