2012-02-13 82 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>()); 
相關問題