2016-05-01 81 views
0

請求時,HttpContext.Current總是空我有Web Api controller Action method我試圖單元測試。我有一個自定義過濾器,它在該動作控制器之前運行。發送從單元測試

我有一個關於HttpContext.Current.User.Identity.Name,我使用我的自定義操作過濾器內部的問題。

當我從Web客戶端發送我的http發佈請求時,它工作得很好。

但是,當我從不是HttpContext.Current我的單元測試發送HTTP POST請求,總是抱怨對null

不明白的地方,什麼是錯。 有人可以請解釋一下嗎?

請注意,我已經看到在here的答案,但不知道我需要在我的情況下添加該代碼的位置。

回答

1

單元測試與通過Web客戶端調用您的api不一樣。

當您使用Web客戶端時,您的API將在您的Web服務器上運行(例如IIS),並且Web服務器將向系統提供che「current」HttpContext

如果你打電話給你代碼你不是在web服務器的上下文中運行的單元測試方法簡單明瞭,但你只是調用它作爲一個類的方法。很明顯,你可以做到這一點,但你需要「模擬」(假的,如果你想的話)當前的HttpContext來模擬你在真實的web服務器上運行。

入住這SO回答關於如何做到這一點的細節。

順便說一下,當你運行集成測試(這意味着通過Web客戶端調用真實的API並檢查輸入輸出結果)時,情況並非如此:在這種情況下,您正在真實環境中運行真實代碼,一切都會正常工作。

0

HttpContext.Current不是在自託管的情況下設置像在您的測試。

但是,您可以圍繞HttpContext.Current創建一個包裝和填充它在運行測試之前。就像這樣:

public static class CurrentHttpContext 
{ 
    public static Func<HttpContextBase> Instance =() => new HttpContextWrapper(HttpContext.Current); 
} 
在您的測試,您可以設置您的 HttpSelfHostServer

然後某處,你填充CurrentHttpContext.Instance。例如與FakeItEasyhttps://github.com/FakeItEasy/FakeItEasy):

var context = A.Fake<HttpContextBase>(); 
CurrentHttpContext.Instance =() => context; 

然後你就可以在你的過濾器訪問CurrentHttpContext.Instance,而不是HttpContext.Current

public class MyAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var context = CurrentHttpContext.Instance(); 
     // stuff 
    } 
}