ここでいくつかの回答を読みました:ビューとコントローラーのテスト、およびモックですが、セッション値(またはその他のコンテキストベースの変数)を読み取って設定するASP.NETMVCコントローラーをテストする方法をまだ理解できません。テストメソッドに(セッション)コンテキストを提供するにはどうすればよいですか?答えをあざけるのですか?誰か例がありますか?基本的に、コントローラーメソッドを呼び出してコントローラーにそのセッションを使用させる前に、セッションを偽造したいと思います。何か案は?
コントローラーコンテキストの偽造に関するStephenWaltherの投稿を確認してください。
ASP.NET MVCヒント#12 –コントローラーコンテキストの偽造
[TestMethod]
public void TestSessionState()
{
// Create controller
var controller = new HomeController();
// Create fake Controller Context
var sessionItems = new SessionStateItemCollection();
sessionItems["item1"] = "wow!";
controller.ControllerContext = new FakeControllerContext(controller, sessionItems);
var result = controller.TestSession() as ViewResult;
// Assert
Assert.AreEqual("wow!", result.ViewData["item1"]);
// Assert
Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]);
}
ASP.NET MVCフレームワークは、インターフェイスの代わりに抽象基本クラスを使用しているため、モックにあまり適していません(つまり、適切にモックを作成するにはセットアップが多すぎ、テスト時に摩擦が大きすぎます)。リクエストごとのセッションベースのストレージの抽象化を作成することができました。これらの抽象化を非常に軽く保ち、コントローラーはリクエストごとまたはセッションごとのストレージをこれらの抽象化に依存します。
たとえば、フォームの認証を管理する方法は次のとおりです。 ISecurityContextがあります:
public interface ISecurityContext
{
bool IsAuthenticated { get; }
IIdentity CurrentIdentity { get; }
IPrincipal CurrentUser { get; set; }
}
次のような具体的な実装で:
public class SecurityContext : ISecurityContext
{
private readonly HttpContext _context;
public SecurityContext()
{
_context = HttpContext.Current;
}
public bool IsAuthenticated
{
get { return _context.Request.IsAuthenticated; }
}
public IIdentity CurrentIdentity
{
get { return _context.User.Identity; }
}
public IPrincipal CurrentUser
{
get { return _context.User; }
set { _context.User = value; }
}
}
MVC RC 1では、ControllerContextはHttpContextをラップし、それをプロパティとして公開します。これにより、モックがはるかに簡単になります。 Moqでセッション変数をモックするには、次のようにします。
var controller = new HomeController();
var context = MockRepository.GenerateStub<ControllerContext>();
context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue");
controller.ControllerContext = context;
詳細については、 Scott Guの投稿 を参照してください。
モックはかなり簡単だと思いました。これは、moqを使用してhttpContextbase(要求、セッション、および応答オブジェクトを含む)をモックする例です。
[TestMethod]
public void HowTo_CheckSession_With_TennisApp() {
var request = new Mock<HttpRequestBase>();
request.Expect(r => r.HttpMethod).Returns("GET");
var httpContext = new Mock<HttpContextBase>();
var session = new Mock<HttpSessionStateBase>();
httpContext.Expect(c => c.Request).Returns(request.Object);
httpContext.Expect(c => c.Session).Returns(session.Object);
session.Expect(c => c.Add("test", "something here"));
var playerController = new NewPlayerSignupController();
memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController);
session.VerifyAll(); // function is trying to add the desired item to the session in the constructor
//TODO: Add Assertions
}
お役に立てば幸いです。
Scott Hanselmanが、MVCを使用して ファイルアップロードを作成 quickappする方法について投稿し、モーキングについて説明し、特に「モックフレンドリーではないものをモックする方法」について説明しています。
私は次のソリューションを使用しました-他のすべてのコントローラーが継承するコントローラーを作成します。
public class TestableController : Controller
{
public new HttpSessionStateBase Session
{
get
{
if (session == null)
{
session = base.Session ?? new CustomSession();
}
return session;
}
}
private HttpSessionStateBase session;
public class CustomSession : HttpSessionStateBase
{
private readonly Dictionary<string, object> dictionary;
public CustomSession()
{
dictionary = new Dictionary<string, object>();
}
public override object this[string name]
{
get
{
if (dictionary.ContainsKey(name))
{
return dictionary[name];
} else
{
return null;
}
}
set
{
if (!dictionary.ContainsKey(name))
{
dictionary.Add(name, value);
}
else
{
dictionary[name] = value;
}
}
}
//TODO: implement other methods here as needed to forefil the needs of the Session object. the above implementation was fine for my needs.
}
}
次に、次のようにコードを使用します。
public class MyController : TestableController { }
HttpContextは静的であるため、Typemock Isolatorを使用してモックを作成します。Typemockには、 ASP.NETユニットテスト と呼ばれる Ivonna 用にビルドされたアドインカスタムもあります。