0

次のような既存のアプリケーションに SessionManager クラスがあります。

public class SessionManagerBase<TKey>
{
    public static void AddItem(TKey key, object item)
    {
        _httpContext.Session[key.ToString()] = item;
    }

    public static T GetItem<T>(TKey key)
    {
        object item = _httpContext.Session[key.ToString()];
        return item == null ? default(T) : (T) Convert.ChangeType(item, typeof (T));
    }

    // etc...

    private static HttpContextBase _httpContext
    {
        get
        {
            return new HttpContextWrapper(HttpContext.Current);
        }
    }
}

私の HomeController には、次のようなコードがあります。

public ActionResult Landing(string id)
{
    SessionManager.GetItem<Campaign>(SessionKeys.Campaign)

    // commented for brevity

    return View("Index");
}

Landing メソッドで単体テストを実行すると、HttpContext.Current が null であるため、テストが失敗します。単体テストで Session オブジェクトをモックしました。Session に Landing メソッド (つまり、Session["SomeValue"]) で直接アクセスしようとすると、機能しますが、SessionManager に依存するコードは壊れています。

要するに、一般的で厳密に型指定された方法で Session 値にアクセスするために使用できるクラスが必要ですが、それは単体テストも可能です。それを達成するためにこのコードを変更する方法について誰か提案がありますか?

4

3 に答える 3

1

テストの HttpContextBase で既にセッションをモックしている場合はSessionManager、カスタム HttpContextBase を受け入れるように変更するだけです (たとえば、[ThreadStatic]フィールドで) 。

または、SessionManagerクラス自体を non-にし、コンストラクターのパラメーターとして をstatic受け取るようにします。HttpContextBase

一般に、決して使用しないでくださいHttpContext.Current。コードをテスト可能または再利用可能にしたい場合。

于 2012-09-14T19:22:17.303 に答える
0

別の抽象化レイヤーを導入することによってのみ、テスト可能にすることができます。それはあなた自身の IOurHttpContext と OurDotNetHttpContext : IOurHttpContext で、実際のアプリ用で、 OurTestHttpContext : IOutHttpContext でテスト用です (後者は moq では必要ありません)。OurDotNetHttpContext は次のようになります。

public interface IOutHttpContext {
    object GetSessionVar( string key );
    void SetSessionVar( string key, object value );
}
public class OurDotNetHttpContext : IOutHttpContext {
    public object GetSessionVar(string key) { return HttpContext.Current.Session[key]; }
    public void SetSessionVar(string key, object value) { HttpContext.Current.Session[key] = value; }
}

とても簡単。しかし、それはもっと洗練されているかもしれません。

于 2012-09-14T19:33:12.733 に答える
0

HttpContext.Current を _httpContext に設定できる可能性があります

于 2012-09-14T23:05:06.357 に答える