1

Simple Membership プロバイダーを使用するコントローラーを単体テストする方法は?

コントローラーは MyViewModel オブジェクトを入力として受け取り、それを DB に挿入します。操作が正常に完了すると、ユーザーはダッシュボードにリダイレクトされます。

コントローラーは依存関係として WebSecurity を持っています。したがって、単体テストを行うと、次の行で HttpContext のパラメーター null 例外が発生します

userLakshya.UserId = WebSecurity.HasUserId ? WebSecurity.CurrentUserId : -1;

HttpContext パラメーターをコントローラーに渡すにはどうすればよいですか?

コード リスト:

    [HttpPost]
    public ActionResult Create(MyViewModel myVM)
    {
        MyModel myModel = myVM.Model;
        if (ModelState.IsValid)
        {
            userLakshya.UserId = WebSecurity.HasUserId ? WebSecurity.CurrentUserId : -1;
            db.MyModels.Add(myModel);
            db.SaveChanges();
            return RedirectToAction("Dashboard");
        }
        return View(myVM);
    }

    [TestMethod]
    public void TestLoginAndRedirectionToDashboard()
    {
        MyController cntlr = new MyController();
        var ret = ulCntlr.Create(new MyViewModel(){
            //Initialize few properties to test
        });
        /*
         * Controller throws parameter null exception for HttpContext
         * => Issue: Should I pass this? since the controller uses WebSecurity inside
         * */
        ViewResult vResult = ret as ViewResult;
        if (vResult != null)
        {
            Assert.IsInstanceOfType(vResult.Model, typeof(UserLakshya));
            UserLakshya model = vResult.Model as UserLakshya;

            if (model != null)
            {
                //Assert few properties from the return type.
            }
        }
    }  
4

1 に答える 1

1

あなたが抱えている問題は、あなたのCreateメソッドが依存性逆転の原則に違反していることです。つまり、あなたのメソッドは「抽象化に依存する必要があります。具象に依存しないでください」.

コードをリファクタリングして、WebSecurity クラスを直接使用する代わりに、ISecurity インターフェイスを作成できるように抽象化を使用する必要があります。次に、 ISecurity の具体的なバージョン (Security など) に WebSecurity への参照を含めることができるため、直接的な依存関係が削除されます。

(データベースの依存関係 (つまり、db メンバー) に対しては既にこれを行っています。コードのセキュリティ面に対してのみこれを行う必要があります。)

例えば

public Interface ISecurity
{
 int GetUserId();
}

次に、代わりに:

userLakshya.UserId = WebSecurity.HasUserId ? WebSecurity.CurrentUserId : -1;

あなたが使用することができます:

userLakshya.UserId = security.GetUserId();

次に、「Create」コントローラーをテストするために、モック フレームワーク (例: Moq )を使用して ISecurity の動作をモックできます (実際、「db」オブジェクトの動作をモックすることもお勧めします)。Moq コードを使用したモックの例は次のとおりです。

var mock = new Mock<ISecurity>();
mock.Setup(security=> security.GetUserId()).Returns("ATestUser");
于 2013-09-30T21:23:05.163 に答える