如何进行单元测试以测试检查请求标头的方法?

我对单元测试非常非常新,我正在尝试编写一个非常简单的测试方法:

public class myClass : RequireHttpsAttribute
{
    public override void OnAuthorization(AuthoizationContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var header = Convert.ToBoolean(request.Headers["Special-Header-Name"]);

        if (!(header || request.IsSecureConnection))
        {
            HandleNonHttpsRequest(filterContext);
        }
    }
}

该方法从RequireHttpsAttribute继承,检查页面是否存在某个头部,如果它缺失或为假,并且页面不安全,则调用HandleNonHttpsRequest ,否则它将不执行任何操作。

我们正在使用Moq和Nunit进行测试。 我已经找到一些资源来帮助用Moq构建一个虚假的HttpContext,但老实说,我不知道如何使用它或在我的单元测试中去哪里去确保假的HttpContexts是或不是导致HandleNonHttpsRequest方法调用。

我非常感谢有关此问题的任何指导。


// arrange
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var headers = new NameValueCollection
{
    { "Special-Header-Name", "false" }
};
request.Setup(x => x.Headers).Returns(headers);
request.Setup(x => x.HttpMethod).Returns("GET");
request.Setup(x => x.Url).Returns(new Uri("http://www.example.com"));
request.Setup(x => x.RawUrl).Returns("/home/index");
context.Setup(x => x.Request).Returns(request.Object);
var controller = new Mock<ControllerBase>();

var actionDescriptor = new Mock<ActionDescriptor>();
var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object);
var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);
var sut = new myClass();

// act
sut.OnAuthorization(filterContext);

// assert
Assert.IsInstanceOfType(filterContext.Result, typeof(RedirectResult));
var redirectResult = (RedirectResult)filterContext.Result;
Assert.AreEqual("https://www.example.com/home/index", redirectResult.Url);

是的,我会使用Moq并创建一个Mock<AuthorizationContext> 。 您需要一系列模拟对象来设置虚假请求,最值得注意的是指定一个假头的NameValueCollection。

var request = new Mock<HttpRequestBase>();
request.SetupGet(c => c.Headers).Return(new NameValueCollection{ /* initialize values here */});
request.SetupGet(c => c.IsSecureConnection).Return(/*specify true or false depending on your test */);

var httpContext = new Mock<HttpContextBase>();
httpContext.SetupGet(c => c.Request).Return(request.Object);


var filterContext = new Mock<AuthorizationContext>();
filterContext.SetupGet(c => c.HttpContext).Return(httpContext.Object);

var myclass = new myClass();
myClass.OnAuthorization(filterContext.Object);

(对不起,如果语法或用法稍微偏离;从我的头顶开始)

您可能需要进入并模拟HandleNonHttpsRequest调用的filterContext上的其他成员。 我有两条建议可以解决这个问题,因为如果你正在测试的方法在filterContext上做了很多复杂的工作,有时会很麻烦:1)直观检查,如果足够简单,模拟所有被调用的块2)创建myClass.OnAuthorizationRequest,但除了对HandleNonHttpsRequest的调用之外,不要实现任何代码。 继续运行测试并修复缺失/不正确的嘲弄成员,直到测试通过。 然后实现OnAuthorizationRequest的实际逻辑,测试和修复(漂洗重复),直到它通过。


我遇到了使用ASP.NET MVC 4接受的解决方案的问题。为了解决它,我嘲笑了http上下文Items属性,否则sut.OnAuthorization导致对象是未定义的异常:

MockHttpContext.Setup(x => x.Items)
    .Returns(new System.Collections.Generic.Dictionary<object, object>());
链接地址: http://www.djcxy.com/p/28025.html

上一篇: How do I make a unit test to test a method that checks request headers?

下一篇: native: ListView, how to push new rows from top