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

C# 如何进行单元测试来测试检查请求头的方法?,c#,asp.net-mvc,unit-testing,nunit,moq,C#,Asp.net Mvc,Unit Testing,Nunit,Moq,我对单元测试非常陌生,我正在尝试为一个非常简单的方法编写一个测试: public class myClass : RequireHttpsAttribute { public override void OnAuthorization(AuthoizationContext filterContext) { var request = filterContext.HttpContext.Request; var header = Convert.T

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

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);
        }
    }
}
此方法继承自
requireHttpAttribute
,它检查某个页眉是否存在于某个页面中,是否丢失或错误,以及该页面是否不安全,然后它将调用
handleOnHttpSrequest
,否则它什么也不做

我们正在使用Moq和Nunit进行测试。我已经找到了一些资源来帮助使用Moq构建fakeHttpContext,但老实说,我不知道如何使用它,也不知道在我的单元测试中应该去哪里,以确保fake HttpContext是否导致调用
HandlenonHttpRequest
方法


我真的很感激任何关于这个问题的指导

是的,我会使用Moq并创建一个
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);
var请求=new Mock();
SetupGet(c=>c.Headers).Return(新的NameValueCollection{/*在这里初始化值*/});
request.SetupGet(c=>c.IsSecureConnection).Return(/*根据测试指定true或false*/);
var httpContext=new Mock();
SetupGet(c=>c.Request).Return(Request.Object);
var filterContext=new Mock();
SetupGet(c=>c.HttpContext).Return(HttpContext.Object);
var myclass=新的myclass();
OnAuthorization(filterContext.Object);
(如果语法或用法有点不正确,很抱歉;请从头开始)

您可能需要进入并模拟HandleNonHttpsRequest调用的filterContext上的任何其他成员。关于这一点,我有两个建议,因为如果您正在测试的方法在filterContext上执行许多复杂的操作,有时可能会很麻烦:1)目视检查,如果足够直接,模拟所有调用的部分2)创建myClass.OnAuthorizationRequest,但是除了调用HandleNonHttpsRequest之外,不要实现任何代码。继续运行测试并修复缺失/错误模拟的构件,直到测试通过。然后实现OnAuthorizationRequest的实际逻辑,测试和修复(重复冲洗),直到通过为止。

//arrange
// 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);
var context=newmock(); var request=newmock(); var headers=newnamevalueCollection { {“特殊头名称”,“假”} }; request.Setup(x=>x.Headers).返回(Headers); Setup(x=>x.HttpMethod).Returns(“GET”); Setup(x=>x.Url).Returns(新Uri(“http://www.example.com")); Setup(x=>x.RawUrl).Returns(“/home/index”); Setup(x=>x.Request).Returns(Request.Object); var controller=newmock(); var actionDescriptor=new Mock(); var controllerContext=new controllerContext(context.Object,new RouteData(),controller.Object); var filterContext=新授权上下文(controllerContext,actionDescriptor.Object); var sut=新的myClass(); //表演 sut.OnAuthorization(过滤上下文); //断言 Assert.IsInstanceOfType(filterContext.Result,typeof(RedirectResult)); var redirectResult=(redirectResult)filterContext.Result; Assert.AreEqual(“https://www.example.com/home/index“,redirectResult.Url);
我在使用ASP.NET MVC 4时遇到了一个问题。为了解决此问题,我模拟了http上下文项属性,否则
sut.OnAuthorization
会导致对象未定义异常:

MockHttpContext.Setup(x => x.Items)
    .Returns(new System.Collections.Generic.Dictionary<object, object>());
MockHttpContext.Setup(x=>x.Items)
.Returns(new System.Collections.Generic.Dictionary());

谢谢!这让我获得了一些成功测试的正确方向