2016-04-28 13 views
2

を模擬します。 このメソッドの単体テストを作成しました。しかし、テストはWebプロセスの外部で実行されるため、HttpContext.Current.Sessionはnullを返し、テストは失敗します。ユニットテストは、私はメソッドを持っているHttpContext

これに対応する方法はありますか?

+1

さ:あなたはのHttpContextに基づいた実装を使用したい、実際のアプリケーションではもちろん、部品番号とAutoFixtureなどのツールも、あなたのためにそれを行うと、今、あなたの人生は簡単で満足しているだろうなど

従来のASP.NETでは難しい。あなた自身の模擬クラスでHttpContext.Sessionへの参照をラップすることをお勧めします。 – Joe

+0

データアクセス層はHttpContextオブジェクトに依存すべきではありません。 – izsl

+0

はい、理想的です。しかし、それに従うためには、私のプロジェクトで大量のコードを再分解する必要があります。 –

答えて

0

テストのために何とかHttpContextという擬似を挿入する必要があります。HttpContextBaseが理想的です。

HttpContextを入れてHttpContextBaseにすることができます。

Inversion of Controlのさまざまなテクニックを読んで、あなたに適したテクニックを見つけてください。

1

まずあなたがHttpContext.Currentを初期化する必要があります:

HttpContext.Current = new HttpContext(new HttpRequest("", "http://blabla.com", "") {}, 
             new HttpResponse(new StringWriter())); 

その後セッションを設定する必要があります:(Necroskillzはhis blogでこれを行う方法を説明しています)

public static void SetFakeSession(this HttpContext httpContext) 
{ 
    var sessionContainer = new HttpSessionStateContainer("id", 
              new SessionStateItemCollection(), 
              new HttpStaticObjectsCollection(), 10, true, 
              HttpCookieMode.AutoDetect, 
              SessionStateMode.InProc, false); 

    httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
              BindingFlags.NonPublic | BindingFlags.Instance, 
              null, CallingConventions.Standard, 
              new[] { typeof(HttpSessionStateContainer) }, 
              null) 
             .Invoke(new object[] { sessionContainer }); 
} 

スニペットは、次のことは、それがどのように動作するかを示しています。

[TestMethod] 
public void TestMethod1() 
{ 
    HttpContext.Current = new HttpContext(new HttpRequest("", "http://blabla.com", "") {}, 
              new HttpResponse(new StringWriter())); 

    HttpContext.Current.SetFakeSession(); 

    HttpContext.Current.Session["foo"] = 1; 

    Assert.AreEqual(1, HttpContext.Current.Session["foo"]); 
} 
1

私はラズを推測しますこの質問への回答はdependency injectionを使用することを学ぶが、私は先に進み、いくつかの指針を提供する。

クラスには、HttpContext内のすべてが必要であるとは考えられません。 integerIdの計算方法は指定していませんが、現在のSessionStateSessionIdのハッシュとしましょう。実際に必要なクラスはすべてです。その特定のものを得るには何かSessionId;その全体がHttpContextである必要はありません。

interface ICurrentSessionIdProvider 
{ 
    string SessionId { get; } 
} 

そして今、あなたのクラスがあります。

// Pull this from a constructor parameter so you can provide any implementation you want 
private readonly ICurrentSessionIdProvider _sessionIdProvider; 

public DataSet someMethod() 
{ 
    int integerId = _sessionIdProvider.SessionId.GetHashCode(); 
    List a = someObj.getList(name, integerId); 
} 

は、今すぐあなたのユニットテストでは、この依存関係を模擬するために些細になります。 HttpContextのモック

class HttpContextCurrentSessionIdProvider : ICurrentSessionIdProvider 
{ 
    // Pull this from a constructor parameter or however you see fit. 
    private readonly HttpContext _httpContext; 

    public SessionId => _httpContext.Current.Session.SessionId; 
} 
関連する問題