How do I make a unit test to test a method that checks request headers?

天大地大妈咪最大 提交于 2019-12-03 02:29:16
// 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);
HackedByChinese

Yes, I'd use Moq and create a Mock<AuthorizationContext>. You'll need a series of mock objects to setup the fake request, most notably to specify a NameValueCollection of fake headers.

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

(sorry if syntax or usage is slightly off; doing this from the top of my head)

You may need to go in and mock any additional members on filterContext that HandleNonHttpsRequest invokes. I have two recommendations for going about this, as it can sometimes be a hassle if the method you are testing is doing lots of complex stuff on filterContext: 1) check visually and, if it's straight forward enough, mock all the invoked pieces 2) create the myClass.OnAuthorizationRequest, but don't implement any code yet other than the call to HandleNonHttpsRequest. Keep running the test and fixing missing/incorrectly mocked members until the test passes. Then implement your actual logic for OnAuthorizationRequest, testing and fixing (rinse repeat) until it passes.

setebos

I encountered an issue with the accepted solution using ASP.NET MVC 4. To resolve it I mocked the http context Items attribute otherwise the sut.OnAuthorization was causing an object is undefined exception:

MockHttpContext.Setup(x => x.Items)
    .Returns(new System.Collections.Generic.Dictionary<object, object>());
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!