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

I am very, very new to unit testing and am trying to write a test for a pretty simple method:

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

This method, which inherits from the RequireHttpsAttribute , checks if a certain header is present from a page, if it's missing or false, and the page is not secure, then it will call HandleNonHttpsRequest , otherwise it does nothing.

We are using Moq and Nunit for testing. I have found some resources to help build a fakeHttpContext with Moq, but honestly I'm not sure how to use it or where to go within my unit tests to ensure that fake HttpContexts are or are not causing the HandleNonHttpsRequest method to call.

I really appreciate any guidance with this issue.


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

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.


我遇到了使用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/28026.html

上一篇: 如何使用moq模拟Controller.User

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