2010-12-15 11 views
2

アクションフィルタのテストケースを作成するにはどうすればよいですか?私はフォーム認証を使用しています。 RequiresAuthenticationアクションフィルターで飾られたベースコントローラーがあります。コントローラのテストケースを実行すると、ログインしたユーザーのデータがCookieから取得されません。アクションフィルタのASP.NET MVCテスト

私はMoqを使用しています。それは私の目標を達成する方法を提供していますか?スコット・ハンゼルマンから

+0

はおそらくhttp://stackoverflow.com/questions/366388/how-can-i-unit-test-my-aspの複製します-net-mvc-controller-that-uses-formsauthentication – rsenna

+0

これは私が探しているものではありません。私はMoqフレームワークを使って偽のhtttpcontextを作成できる場所を探しています。 – nimi

答えて

2

これblog postも部品番号、とりわけ異なるモックフレームワークのためのFakeHttpContext含むMvcMockHelpersをカバー:

using System; 
using System.Web; 
using System.Text.RegularExpressions; 
using System.IO; 
using System.Collections.Specialized; 
using System.Web.Mvc; 
using System.Web.Routing; 
using Moq; 

namespace UnitTests 
{ 
    public static class MvcMockHelpers 
    { 
     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>(); 

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

      return context.Object; 
     } 

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

     public static void SetFakeControllerContext(this Controller controller) 
     { 
      var httpContext = FakeHttpContext(); 
      ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller); 
      controller.ControllerContext = context; 
     } 

     static string GetUrlFileName(string url) 
     { 
      if (url.Contains("?")) 
       return url.Substring(0, url.IndexOf("?")); 
      else 
       return url; 
     } 

     static NameValueCollection GetQueryStringParameters(string url) 
     { 
      if (url.Contains("?")) 
      { 
       NameValueCollection parameters = new NameValueCollection(); 

       string[] parts = url.Split("?".ToCharArray()); 
       string[] keys = parts[1].Split("&".ToCharArray()); 

       foreach (string key in keys) 
       { 
        string[] part = key.Split("=".ToCharArray()); 
        parameters.Add(part[0], part[1]); 
       } 

       return parameters; 
      } 
      else 
      { 
       return null; 
      } 
     } 

     public static void SetHttpMethodResult(this HttpRequestBase request, string httpMethod) 
     { 
      Mock.Get(request) 
       .Expect(req => req.HttpMethod) 
       .Returns(httpMethod); 
     } 

     public static void SetupRequestUrl(this HttpRequestBase request, string url) 
     { 
      if (url == null) 
       throw new ArgumentNullException("url"); 

      if (!url.StartsWith("~/")) 
       throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\"."); 

      var mock = Mock.Get(request); 

      mock.Expect(req => req.QueryString) 
       .Returns(GetQueryStringParameters(url)); 
      mock.Expect(req => req.AppRelativeCurrentExecutionFilePath) 
       .Returns(GetUrlFileName(url)); 
      mock.Expect(req => req.PathInfo) 
       .Returns(string.Empty); 
     } 
    } 
} 

ASP.NET MVCテストヘルパーのためのもう一つの良いリソースがCodePlexの上MvcContribプロジェクトです。あなたはFakeHttpContextがあなたのアクションフィルタをテストすることができていた後

var context = new ActionExecutedContext(); 
context.HttpContext = MvcMockHelpers.FakeHttpContext(); 
context.Result = new EmpytResult(); // or whatever the default result should be 

var filter = new MyCustomAttribute(); 
filter.OnActionExecuted(context); 

Assert.True(context.Result is EmpytResult); 
... 
+0

仮想URLが必要な理由は誰でも知っています。これを強制する良い理由はありますか? –

関連する問題