2010-12-15 50 views
2

Comment puis-je écrire un scénario de test pour les filtres d'action? J'utilise l'authentification par formulaire. J'ai le contrôleur de base décoré du filtre d'action RequiresAuthentication. Lorsque j'exécute le scénario de test du contrôleur, je ne reçois pas les données de l'utilisateur connecté à partir des cookies.Test ASP.NET MVC pour les filtres d'action

J'utilise Moq; Est-ce que cela fournit un moyen d'atteindre mon objectif?

+0

probablement un double de http://stackoverflow.com/questions/366388/how-can-i-unit-test-my-asp -net-mvc-controller-that-uses-formsauthentication – rsenna

+0

non ce n'est pas celui que je cherche. Je cherche quelque chose où je peux employer le cadre de Moq pour créer le faux htttpcontext. – nimi

Répondre

2

Cette blog post de Scott Hanselmann couvre MvcMockHelpers y compris FakeHttpContext pour différents cadres moqueurs entre autres aussi MOQ:

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

Une autre bonne ressource pour les aides de test ASP.NET MVC est le projet MvcContrib sur CodePlex.

Une fois que vous avez un FakeHttpContext vous pouvez tester votre filtre d'action:

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

Quelqu'un sait pourquoi il a besoin d'une URL virtuelle; Y a-t-il une bonne raison d'appliquer cela? –