如何为动作过滤器编写测试用例?我正在使用表单身份验证。 我有使用RequiresAuthentication动作过滤器修饰的基本控制器。当我执行控制器的测试用例时,我没有从cookie中获取登录用户的数据。
我正在使用Moq;它是否提供了实现目标的方法?
答案 0 :(得分:2)
来自Scott Hanselmann的这个blog post涵盖了MvcMockHelpers,包括FakeHttpContext
,用于不同的模拟框架以及其他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);
}
}
}
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);
...