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

本文关键字:请求 方法 检查 测试 何进行 单元测试 | 更新日期: 2023-09-27 18:24:14

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

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,检查页面中是否存在某个标头,如果该标头丢失或为false,并且该页面不安全,则它将调用HandleNonHttpsRequest,否则不执行任何操作。

我们正在使用Moq和Nunit进行测试。我已经找到了一些资源来帮助用Moq构建fakeHttpContext,但老实说,我不知道如何使用它,也不知道在我的单元测试中去哪里,以确保fakeHttpContexts正在或没有导致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>。您将需要一系列mock对象来设置假请求,尤其是指定一个由假标头组成的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>());