を模擬します。 このメソッドの単体テストを作成しました。しかし、テストはWebプロセスの外部で実行されるため、HttpContext.Current.Session
はnullを返し、テストは失敗します。ユニットテストは、私はメソッドを持っているHttpContext
これに対応する方法はありますか?
を模擬します。 このメソッドの単体テストを作成しました。しかし、テストはWebプロセスの外部で実行されるため、HttpContext.Current.Session
はnullを返し、テストは失敗します。ユニットテストは、私はメソッドを持っているHttpContext
これに対応する方法はありますか?
テストのために何とかHttpContext
という擬似を挿入する必要があります。HttpContextBase
が理想的です。
にHttpContext
を入れてHttpContextBase
にすることができます。
Inversion of Controlのさまざまなテクニックを読んで、あなたに適したテクニックを見つけてください。
まずあなたが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"]);
}
私はラズを推測しますこの質問への回答はdependency injectionを使用することを学ぶが、私は先に進み、いくつかの指針を提供する。
クラスには、HttpContext内のすべてが必要であるとは考えられません。 integerId
の計算方法は指定していませんが、現在のSessionState
のSessionId
のハッシュとしましょう。実際に必要なクラスはすべてです。その特定のものを得るには何か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;
}
さ:あなたはのHttpContextに基づいた実装を使用したい、実際のアプリケーションではもちろん、部品番号とAutoFixtureなどのツールも、あなたのためにそれを行うと、今、あなたの人生は簡単で満足しているだろうなど
従来のASP.NETでは難しい。あなた自身の模擬クラスでHttpContext.Sessionへの参照をラップすることをお勧めします。 – Joe
データアクセス層はHttpContextオブジェクトに依存すべきではありません。 – izsl
はい、理想的です。しかし、それに従うためには、私のプロジェクトで大量のコードを再分解する必要があります。 –