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

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

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

此方法inheritance自RequireHttpsAttribute ,检查页面是否存在某个标头,如果它丢失或为false,并且页面不安全,则它将调用HandleNonHttpsRequest ,否则它不执行任何操作。

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

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

 // arrange var context = new Mock(); var request = new Mock(); 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(); var actionDescriptor = new Mock(); 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 。 您需要一系列模拟对象来设置虚假请求,最明显的是指定伪标头的NameValueCollection。

 var request = new Mock(); 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(); httpContext.SetupGet(c => c.Request).Return(request.Object); var filterContext = new Mock(); 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 接受的解决方案的问题。为了解决它,我sut.OnAuthorization了http上下文Items属性,否则sut.OnAuthorization导致对象是未定义的exception:

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