簡體   English   中英

如何正確模擬HttpContextBase,以便我的單元測試正常工作

[英]How to Mock HttpContextBase correctly so my unit tests are working

賦予以下功能:

public static void Write(HttpContextBase contextBase, IUnitOfWork unitOfWork, LogLevel level, string title, string message, params AdditionalProperty[] properties)
{
    // Some variables that are set for writing the logs.
    //      - client: When the HttpContext is null, 'N.A.' is used, otherwise the I.P. address of the requesting computer.
    //      - userIdentifier: When the HttpContext exists and a value is stored in the cookie, the value of the cookie, otherwise an empty guid.
    //      - requestIdentifier: When the context is existing and a request have been made on a controller, a unique value identifying this request, otherwise an empty guid.

    string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    string userIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.CurrentHandler != null && CookieManager.Exists("UserIdentifier")) ? CookieManager.Read("UserIdentifier", Guid.NewGuid().ToString().ToUpper()) : Guid.Empty.ToString();
    string requestIdentifier = (contextBase.ApplicationInstance != null && contextBase.ApplicationInstance.Context != null && contextBase.ApplicationInstance.Context.Cache != null && HttpContext.Current.Cache["RequestIdentifier"] != null) ? HttpContext.Current.Cache["RequestIdentifier"].ToString() : Guid.Empty.ToString();

    // Additional code for processing is done here.
}

我正在為工作單元使用HttpContextBase和接口,因為我知道單元測試比工作起來容易。

現在,我在單元測試中使用Moq來使用Mocking功能,但我為此感到吃力。

讓我們看一下變量cliënt:

string client = (contextBase.ApplicationInstance == null || contextBase.ApplicationInstance.Context.CurrentHandler == null) ? "N.A." : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

我想知道如何通過模擬必要的對象來設置我的單元測試。

這是我當前的單元測試:

var context = new Mock<HttpContextBase>();
var httpApplicationMock = new Mock<HttpApplication>();

httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object); --> FAILS
context.SetupGet(c => c.ApplicationInstance).Returns(httpApplicationMock.Object);

httpApplicationMock的設置失敗,因為context.Object不是有效的參數,但是我需要傳遞HttpContext。

有人可以給我一點點正確方向的推動力嗎?

該行失敗,因為Context返回HttpContext類型,而不是HttpContextBase

httpApplicationMock.SetupGet(x => x.Context).Returns(context.Object);

創建context作為Mock<HttpContext>實例也無濟於事,因為它是一個密封的類,而Moq無法模擬密封的類。

您可以在接口后面隱藏有關HttpContext的實現細節。 這是為您顯示示例的博客文章: http : //volaresystems.com/Blog/post/2010/08/19/Dont-mock-HttpContext

經過一些進一步的測試,我意識到了問題所在。

首先,非常重要,我正在使用MSTest。 因此,問題不依賴於在構造函數中創建的存儲庫,因為對於通過MSTest運行的每個測試,都將執行構造函數。 這樣就消除了。

經過進一步檢查,我意識到,要從設置存儲庫檢索設置,我使用了一個實例化為Singleton的類,這就是問題所在。

當我使用具有指定設置的單元測試運行我的第一個文件時,由於仍需要創建該設置,因此一切正常。

但是在第二個文件中,我使用了另一個設置,但是由於負責獲取設置的管理器是Singleton,因此未檢索到新設置,而是使用了前一個設置。

這引起了問題。

無論如何,要感謝那些試圖幫助我解決這種情況的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM