2012-11-12 8 views
10

私は現在ユニットテストのためにScott Hanselmans HTTP context mockを使用していました。これはMVC 3でうまくいきました。私は次のコードの呼び出しをテストするために使っていました。私が最初に私が問題に遭遇したMVC 4に私のアプリを変換する場合MVC 4 Mocking HttpContext - 模擬する方法DisplayModeProvider

public class PartialViewRenderer : IPartialViewRenderer 
{ 
    public string Render(Controller controller, string viewName, object model) 
    { 
     if (string.IsNullOrEmpty(viewName)) 
      viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); 

     controller.ViewData.Model = model; 

     using (StringWriter sw = new StringWriter()) 
     { 
      ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
      ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, 
                 controller.ViewData, controller.TempData, sw); 
      viewResult.View.Render(viewContext, sw); 

      return sw.GetStringBuilder().ToString(); 
     } 
    } 
} 

、それは実行時例外を得ていました。だから私はHanselmans MockHelpersで次のメソッドを変更する上で私を上陸され、通過して、定着に必要なものを固定してみました:(それは「ヌル」の例外を吹いていたので、私は基本的にHttpContext.Itemsが返さ取得するように変更)

public static HttpContextBase FakeHttpContext() 
    { 
     var context = new Mock<HttpContextBase>(); 
     var request = new Mock<HttpRequestBase>(); 
     var response = new Mock<HttpResponseBase>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     var server = new Mock<HttpServerUtilityBase>(); 
     var cookies = new HttpCookieCollection(); 
     var items = new ListDictionary(); 

     request.Setup(r => r.Cookies).Returns(cookies); 
     response.Setup(r => r.Cookies).Returns(cookies); 

     context.Setup(ctx => ctx.Items).Returns(items); 

     context.SetupGet(ctx => ctx.Request).Returns(request.Object); 
     context.SetupGet(ctx => ctx.Response).Returns(response.Object); 
     context.SetupGet(ctx => ctx.Session).Returns(session.Object); 
     context.SetupGet(ctx => ctx.Server).Returns(server.Object); 

     return context.Object; 
    } 

public static void SetFakeControllerContext(this Controller controller, RouteData route) 
    { 
     var httpContext = FakeHttpContext(); 

     ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller); 

     controller.ControllerContext = context; 
    } 
ここで

私が試してみて、私はこのテストを実行したときに(私もまだアサートに入れhaventは)HTTPコンテキストのこのモックに今

[Test] 
    public void test() 
    { 
     _contactsController = _container.Resolve<ContactsController>(); 

     var route = new RouteData(); 

     route.Values.Add("controller", "ContactsController"); 
     route.Values.Add("action", "GetEditContactDetailsDialog"); 

     _contactsController.SetFakeControllerContext(route); 

     var result = _contactsController.GetEditContactDetailsDialog("1"); 
    } 

を行う必要がある変更内容見極める必要があり、非常に単純なNUnitのテストこれはPartialViewRenderer.RenderコールのViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);行で呼び出されます。次のスタックトレースがあります。

at System.WebPages.DisplayModeProvider。 < .ctor> b__2(HttpContextBaseコンテキスト)at System.Web.WebPages.DefaultDisplayMode.CanHandleContext(HttpContextBase httpContext) at System.WebPages.DisplayModeProvider。 <> c__DisplayClass6.b__5(IDisplayModeモード)System.Linq.Enumerable.WhereListIterator 1.MoveNext() at System.Collections.Generic.List 1..ctorで (IEnumerableを1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1ソース)System.Web.WebPages.DisplayModeProvider.GetAvailableDisplayModesForContext(HttpContextBaseのHttpContext、IDisplayMode currentDisplayMode) におけるシステムで.Web.Mvc.VirtualPathProviderViewEngine.GetPath(controllerContext controllerContext、文字列[]位置、文字列[] areaLocations、ストリングlocationsPropertyName、文字列名、ストリングコントローラ名、文字列cacheKeyPrefix、ブールuseCache、文字列[] & searchedLocations)

それ私はそこに入り、DisplayModeProviderをモックすることはできないようです。 Per the MVC source Code誰にもこれに対する解決策がありますか?私はどこにでもこのソリューションを見つけることはできませんでした。

+0

私はDisplayModeのモックに関する似たような問題を抱えています。私はあなたが何か解決策を見つけることができたのだろうか? – Shahin

答えて

0

DisplayModeはインターフェイスIDisplayModeを実装しているので、(Moqを使用して)注入する模擬を作成できるはずです。 DisplayModeProviderにはReflection経由で呼び出すことができるSetDisplayMode(保護)メソッドがあります。あなたがのDisplayModeとの依存関係を見つけることができ、これを使用して

var context = new Mock<HttpContextBase>(MockBehavior.Strict); 

6

まず、initは同様MockBehavior.Strictと皮肉っ。

第二に、のDisplayModeはasp.netのMVC 4の新機能です:

http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253810

だから、それは使用の決定的ビューのRequest.Browserのparamsを取得します。ブラウザ用モック追加:

 var browser = new Mock<HttpBrowserCapabilitiesBase>(MockBehavior.Strict); 
     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     var session = new Mock<HttpSessionStateBase>(MockBehavior.Strict); 
     var server = new Mock<HttpServerUtilityBase>(MockBehavior.Strict); 
     var cookies = new HttpCookieCollection(); 
     var items = new ListDictionary(); 

     browser.Setup(b => b.IsMobileDevice).Returns(false); 

     request.Setup(r => r.Cookies).Returns(cookies); 
     request.Setup(r => r.ValidateInput()); 
     request.Setup(r => r.UserAgent).Returns("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"); 
     response.Setup(r => r.Cookies).Returns(cookies); 

     request.Setup(r => r.Browser).Returns(browser.Object); 
     context.Setup(ctx => ctx.Items).Returns(items); 
+0

私はまだこれを動作させる必要があります。私は今、別のエラーが発生している、私は今夜それを理解することを願っています。 – Etch

+0

ありがとう、このコードは魅力のように動作します。 – msi

+0

System.Web.Web.Pages.FileExcistenceCacheコンストラクタの 'NullReferenceException'で失敗して、' ViewEngineCollection.FindPartialView() 'を呼び出すときに何か不足しているようです。この回答は、魅力のような他のシナリオではうまくいくかもしれません。 – Manfred

関連する問題