3

コントローラーの単体テストを行っています。

コントローラー メソッドの 1 つで、セッション変数を設定しています。

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

これを単体テストするにはどうすればよいですか?問題は、テスト時に Session プロパティが null であることです。Session プロパティが読み取り専用のため、注入できません。

サードパーティのツールやモックを使用したくありません。

4

3 に答える 3

6

コントローラーメソッドで Session["foo"] のようなものを使用しないでください。ベスト プラクティスは、アクション メソッドがコンテキストのようなグローバル オブジェクトを認識しないようにすることです。アクションメソッドに必要なものはすべて、引数の形で彼女に与える必要があります。モデルバインディングの組み込みメカニズムはまさにそのように機能することに注意してください-Request.Form []を使用しないでください。「舞台裏の誰か」にそれを引数としてアクションに渡します。

セッションについても同じことができます - セッションから入力したい引数を認識する方法を知っている非常に単純な ValueProvider を書いてください。プロダクションでは、アクションはセッションで機能しますが、テストでは、引数として必要な値を単純に渡すことはできません。

インスピレーションについては、http://www.prideparrot.com/blog/archive/2012/7/how_to_create_a_custom_session_value_providerをご覧ください。

于 2012-09-14T14:16:43.907 に答える
1

Session プロパティが読み取り専用のため、注入できません。

これは、setter インジェクションを使用できないことを意味しますが、コンストラクター インジェクションを使用できますか。つまり、次のようなコントローラーのコンストラクターを追加できます。

MyController(Session session)
{
    m_session = session;

    // then call your main constructor
}

Session getSession()
{
    return m_session;
}

その後、テスト中にこの別のコンストラクターを使用できます。

于 2012-09-14T11:23:36.257 に答える
0

@rouenに同意します。Session["foo"] を直接使用しないでください。しかし、ValueProvider ans を持つことは実用的な解決策ではないかもしれないと思います。保存する変数はごくわずかであり、これらの値はおそらく完全なモデルではない可能性があります。したがって、私のアプローチは Vic Smith が示唆するものと似ていますが、より IOC (および Mock) に適しています。

セッション変数を取得するためのプロバイダー (つまり、サービス) を作成します。

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);
    }

コントローラーを変更して、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 の独自のテスト実装を作成し、コントローラーに渡します。

于 2014-11-09T09:15:03.627 に答える