2012-02-13 98 views
12

我非常,非常新的单元测试,我试图写一个测试一个非常简单的方法:如何进行单元测试以测试检查请求标头的方法?

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继承,检查是否有某些头是从页当前,如果是丢失或错误,页面是不是安全的,那么它会调用HandleNonHttpsRequest,否则什么也不做。

我们使用的起订量和NUnit进行测试。我已经发现了一些资源,帮助建立与起订量一个fakeHttpContext,但老实说,我不知道如何使用它或在哪里我的单元测试中去,以确保假HttpContexts是或不是导致HandleNonHttpsRequest方法来调用。

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

回答

20
// 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); 
+1

+1指出了测试的AAA部分。 – CodingWithSpike 2012-02-13 16:12:34

+0

谢谢!这让我朝着正确的方向去取得一些成功的测试。 – Dredj 2012-02-14 15:13:43

1

是的,我会用最小起订量,并创建一个Mock<AuthorizationContext>。您需要一系列模拟对象来设置虚假请求,最值得注意的是指定一个假头的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); 

(抱歉,如果语法或使用稍微偏离;从我的头顶做这个)

你可能需要去和嘲笑的filterContext任何其他成员HandleNonHttpsRequest调用。我有去了解,因为它有时是一个麻烦,如果你要测试的方法是filterContext做很多复杂的东西两条建议:1)目视检查,如果它是直截了当不够,模拟所有的调用块2)创建myClass.OnAuthorizationRequest,但除了对HandleNonHttpsRequest的调用之外,不要实现任何代码。继续运行测试并修复缺失/不正确的嘲弄成员,直到测试通过。然后实现OnAuthorizationRequest的实际逻辑,测试和修复(漂洗重复),直到它通过。

0

我遇到的问题与the accepted solution使用ASP.NET MVC 4,要解决它,我嘲笑了HTTP上下文项目属性,否则sut.OnAuthorization是导致对象是不确定的例外:

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