簡體   English   中英

如何在mvc中對控制器中的會話變量進行單元測試

[英]how to unit test for session variable in controller in mvc

我正在對我的控制器進行單元測試。

在我的一個控制器方法中,我設置了Session變量:

public void Index()
{       Session["foo"] = "bar";
        return View();
}

我怎樣才能對此進行單元測試? 問題是測試時Session屬性為null。 無法進行注入,因為Session屬性是只讀的。

我不想使用任何第三方工具或嘲笑。

只是不要在控制器方法中使用Session [“foo”]之類的東西。 最佳實踐是讓操作方法不知道任何類似上下文的全局對象。 你的行動方法需要的一切都應該以爭論的形式提供給她。 請注意,模型綁定的內置機制與此完全相同 - 您不使用Request.Form [],您讓“幕后某人”將其作為參數傳遞給您的操作。

現在對於會話你可以做同樣的事情 - 寫一個非常簡單的ValueProvider,它將知道如何識別你想要從會話中填充的參數,並且你已經完成了。 在生產中,您的操作將與會話一起使用,在測試中您不能簡單地將任何您想要的值作為參數傳遞給它們。

如需靈感,請查看http://www.prideparrot.com/blog/archive/2012/7/how_to_create_a_custom_session_value_provider

無法進行注入,因為Session屬性是只讀的。

這意味着你不能使用setter注入,但是你可以使用構造函數注入,即為你的控制器添加一個類似於的構造函數:

MyController(Session session)
{
    m_session = session;

    // then call your main constructor
}

Session getSession()
{
    return m_session;
}

然后,您可以在測試期間使用此單獨的構造函數。

我同意@rouen。 不要直接使用Session [“foo”]。 但我認為使用ValueProvider ans可能不是一個實用的解決方案,因為我們只存儲很少的變量,而這些值可能並且很可能不是完整的模型。 所以我的方法類似於維克史密斯的建議,但更多的是IOC(和模擬)友好。

我會創建一個提供程序(即服務)來檢索會話變量

public class SessionVariableProvider : ISessionVariableProvider
    {
        public object GetSessionValue(string key)
        {
            if (!HttpContext.Current.Session.IsNewSession 
                    && HttpContext.Current.Session[key] != null)
                {
                    return HttpContext.Current.Session[key];
                }
                throw new ArgumentNullException(key);
        }
        public void SetSessionValue(string key, object value)
        {
            HttpContext.Current.Session[key] = value;
        }
    }
    public interface ISessionVariableProvider
    {
        object GetSessionValue(string key);
        void SetSessionValue(string key, object value);
    }

修改Controller期望ISessionVariableProvider作為參數。

public class TestController: Controller
    {
        protected readonly ISessionVariableProvider _sessionVariableProvider;

        protected InowiaControllerBase(ISessionVariableProvider sessionVariableProvider)
        {
            Guard.ArgumentNotNull(sessionVariableProvider, "sessionVariableProvider");

            this._sessionVariableProvider = sessionVariableProvider;
        }
        public ActionResult Index()
        {       
            _sessionVariableProvider.SetSessionValue("foo", "bar");
            var foo2 = (string)_sessionVariableProvider.GetSessionValue("foo2");
            return View();
        }
    }

在測試時創建自己的ISessionVariableProvider測試實現並將其傳遞給控制器​​。

暫無
暫無

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

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