0

以下のように、すべてのコントローラー インスタンスに適用されるベース コントローラーでポリシーをセットアップする必要があります。

  public class BaseController : Controller
    {

        private IPolicy Policy;

        public BaseController()
        {
            this.Policy= new Policy(HttpContext);
        }
    }

Policy クラス内で、次のようなことを行う必要があります。

   this.httpContextBase.User.

質問: (更新)

HttpContext と単体テストの使用に関して BaseController を設計するより良い方法は何ですか。

4

1 に答える 1

6

HttpContextを単体テストする正しい方法は何ですか?

絶対無理。HttpContextこのコンテキストがまだ初期化されていないときに、コントローラーのコンストラクター内で使用しています。このコードはテストできないだけでなく、アプリケーションを実行すると NRE でクラッシュします。コントローラーのコンストラクターで HttpContext 関連のものを使用しないでください。

1 つの可能性は、コードをリファクタリングし、Initializeメソッド内でこれを実行することです。

public class BaseController : Controller
{
    private IPolicy Policy;

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);
        this.Policy = new Policy(HttpContext);
    }
}

そうは言っても、それは私が推奨するアプローチではありません。多くの人がアンチパターンと見なしているサービス ロケーションの代わりに、依存性注入を使用することをお勧めします。

そう:

public abstract class BaseController : Controller
{
    protected IPolicy Policy { get; private set; }

    protected BaseController(IPolicy policy)
    {
        Policy = policy;
    }
}

あとは、好きな依存性注入フレームワークを構成して、正しいインスタンスをコンストラクターに注入するだけです。たとえば、Ninject.Mvc3 では、これは 1 行のコードで実現されます。

kernel.Bind<IPolicy>().To<Policy>();

これで、HttpContext を気にすることなく、単体テストでこの IPolicy を自由にモックできるようになりました。

たとえば、単体テストする次のコントローラーがあるとします。

public class FooController : BaseController
{
    public FooController(IPolicy policy): base(policy)
    { }

    [Authorize]
    public ActionResult Index()
    {
        Policy.DoSomething();
        return View();
    }
}

あとは、お気に入りのモック フレームワーク (私の場合は Rhino Mocks) を選択して、モックを作成するだけです。

[TestMethod]
public void Index_Action_Should_DoSomething_With_The_Policy()
{
    // arrange
    var policyStub = MockRepository.GenerateStub<IPolicy>();
    var sut = new FooController(policyStub);

    // act
    var actual = sut.Index();

    // assert
    Assert.IsInstanceOfType(actual, typeof(ViewResult));
    policyStub.AssertWasCalled(x => x.DoSomething());
}
于 2012-05-26T07:19:26.533 に答える