2013-03-06 30 views
10

私はユニットテストのためにNUnitMoqライブラリを使用します。 私のコントローラのアクションはget an absolute url of an Actionにそれを使用しているので、私はオーバーロードされたUrl.Action(string, string, object, string)をモックする必要があります。ASP.NET MVCのMocking Controller.Url.Action(文字列、文字列、オブジェクト、文字列)

今の私の試みは、(MockUrlActionテストを見て):

[TestFixture] 
public class ControllerTests 
{ 
    [Test] 
    public void MockUrlAction() 
    { 
     var controller = new TestController(); 

     controller.Url = new UrlHelper(new RequestContext(MvcMoqHelpers.FakeHttpContext(), new RouteData()), GetRouteCollection()); 

     // it works 
     Assert.AreEqual("/PathToAction", controller.Url.Action("TestAction")); 

     // but it doesn't work 
     Assert.AreEqual("http://example.com/PathToAction", controller.Url.Action("TestAction", null, null, "http")); 
    } 

    private RouteCollection GetRouteCollection() 
    { 
     BundleTable.MapPathMethod = MapBundleItemPath; 
     var routes = new RouteCollection(); 
     RouteConfig.RegisterRoutes(routes); 

     var adminArea = new AdminAreaRegistration(); 
     var adminAreaRegistrationContext = new AreaRegistrationContext(adminArea.AreaName, routes); 
     adminArea.RegisterArea(adminAreaRegistrationContext); 

     return routes; 
    } 
} 

public static class MvcMoqHelpers 
{ 
    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>(); 

     request.Setup(r => r.AppRelativeCurrentExecutionFilePath).Returns("/"); 
     request.Setup(r => r.ApplicationPath).Returns("/"); 
     response.Setup(s => s.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s); 

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

     return context.Object; 
    } 
} 

そしてライン

Assert.AreEqual("http://example.com/PathToAction", controller.Url.Action("TestAction", null, null, "http")); 

で、私はそれが私のために奇妙だ例外

System.NullReferenceException : Object reference not set to an instance of an object. 
at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues) 
at System.Web.Mvc.UrlHelper.Action(String actionName, String controllerName, Object routeValues, String protocol) 

を取得controller.Url.Action("TestAction")は問題なく動作しますが、controller.Url.Action("TestAction", null, null, "http")はありません。

P.S. MvcMoqHelpers.FakeHttpContext()はhereです。質問に答えるのに役立つかもしれません。

質問:私はどのようにUrl.Action(文字列、文字列、オブジェクト、文字列)を偽装することができますか?

ありがとうございました。そう、あなたのUrl.Action過負荷で使用すると、ホスト名とプロトコルを提供していない -

public static HttpContextBase FakeHttpContext(string url) 
{ 
    HttpContextBase context = FakeHttpContext(); 
    context.Request.SetupRequestUrl(url); 
    return context; 
} 

理由は次のとおりです。

+0

context.Request.SetupRequestUrl(url)のURLはどうですか? – Nenad

+0

[ASP.NET MVC:Mock controller.Url.Action](https://stackoverflow.com/questions/1367616/asp-net-mvc-mock-controller-url-action)の可能な複製 –

答えて

10

あなたがRequest.Urlを設定する必要があり、あなたが提供するチュートリアルのコードのその部分を持っていますMVCはRequest.Urlからそれらの値を抽出しようとします

if (!String.IsNullOrEmpty(protocol) || !String.IsNullOrEmpty(hostName)) 
{ 
    Uri requestUrl = requestContext.HttpContext.Request.Url; 
    protocol = (!String.IsNullOrEmpty(protocol)) ? protocol : Uri.UriSchemeHttp; 
    hostName = (!String.IsNullOrEmpty(hostName)) ? hostName : requestUrl.Host; 
+0

あなたが正しいと思われます。このチュートリアルの 'public static void SetupRequestUrl(このHttpRequestBaseリクエスト、文字列url)'メソッドを 'mock.Setup(req => req.Url)という行を追加して修正しました.Returns(新しいUri(新しいhttp:// localhost/")、url));'オーバーロードされた 'FakeHttpContext(string url)'を呼び出すと今は動作するようです。私はそれが最も簡単な修正方法であるかどうかはわかりませんが、とにかく私はあなたの答えを受け入れます。ありがとう。 – kasitan

関連する問題