web-dev-qa-db-ja.com

ASP.NET MVCのUser.Identityのモック

ASP.NET MVC 2.0 Webサイトの単体テストを作成する必要があります。このサイトはWindows認証を使用しています。

私は、HttpContextを処理するコードのHTTPコンテキストをモックする必要性について読んでいます。 DIパターンも取り始めた気がします。 (クラスにIRepository型の属性を指定し、コントローラーをインスタンス化するときにRepositoryオブジェクトを渡します。)

しかし、私が理解していないのは、User.Identityを通じて利用可能なWindowsプリンシパルオブジェクトをモックする適切な方法です。これはHttpContextの一部ですか?

これを実証する記事(または本の推奨事項)へのリンクを含む団体はありますか?

おかげで、

トレイ・キャロル

39
Trey Carroll

IoCを使用してこれを抽象化し、ある程度の成功を収めました。最初に、現在ログインしているユーザーを表すクラスを定義しました。

public class CurrentUser
{
    public CurrentUser(IIdentity identity)
    {
        IsAuthenticated = identity.IsAuthenticated;
        DisplayName = identity.Name;

        var formsIdentity = identity as FormsIdentity;

        if (formsIdentity != null)
        {
            UserID = int.Parse(formsIdentity.Ticket.UserData);
        }
    }

    public string DisplayName { get; private set; }
    public bool IsAuthenticated { get; private set; }
    public int UserID { get; private set; }
}

値を設定するには、コンストラクターでIIdentityを使用します。単体テストの場合、IIdentity依存関係をバイパスできるように別のコンストラクターを追加できます。

次に、Ninjectを使用し(お気に入りのIoCコンテナーを選択します。問題ありません)、IIdentityのバインディングを次のように作成します。

Bind<IIdentity>().ToMethod(c => HttpContext.Current.User.Identity);

次に、コントローラーの内部で、コンストラクターで依存関係を宣言します。

CurrentUser _currentUser;

public HomeController(CurrentUser currentUser)
{
    _currentUser = currentUser;
}

IoCコンテナは、HomeControllerCurrentUserオブジェクトを受け取り、CurrentUserコンストラクタがIIdentityを受け取ることを認識します。依存関係を自動的に解決します。コントローラは、現在ログオンしているユーザーが誰であるかを知ることができます。 FormsAuthenticationを使用すると、かなりうまくいくようです。この例をWindows認証に適合させることができる場合があります。

31
John Nelson

MVC 2.0についてはわかりませんが、新しいバージョンではControllerContextをモックできます。

// create mock principal
var mocks = new MockRepository(MockBehavior.Default);
Mock<IPrincipal> mockPrincipal = mocks.Create<IPrincipal>();
mockPrincipal.SetupGet(p => p.Identity.Name).Returns(userName);
mockPrincipal.Setup(p => p.IsInRole("User")).Returns(true);

// create mock controller context
var mockContext = new Mock<ControllerContext>();
mockContext.SetupGet(p => p.HttpContext.User).Returns(mockPrincipal.Object);
mockContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

// create controller
var controller = new MvcController() { ControllerContext = mock.Object };

も参照してください c#での認証に依存するMVCコントローラーアクションを単体テストする方法?

19
MovGP0

Scott Hanselman彼のブログ の使用方法 IPrincipal とModelBinderの使用方法を示し、IPrincipalをモックしてコントローラーを簡単にテストできるようにしています。

10
Soe Moe

MVC4のユーザー名とSIDをモックする例次のアクションのユーザー名とSID(Windows認証)をテストする必要があります。

[Authorize]
public class UserController : Controller
{
    public ActionResult Index()
    {
        // get Username
        ViewBag.Username = User.Identity.Name;

        // get SID
        var lIdentity = HttpContext.User.Identity as WindowsIdentity;
        ViewBag.Sid = lIdentity.User.ToString();

        return View();
    }
}

MoqVisual Studio Test Tools を使用しています。テストは次のように実装されます。

[TestMethod]
public void IndexTest()
{
    // Arrange
    var myController = new UserController();
    var contextMock = new Mock<ControllerContext>();
    var httpContextMock = new Mock<HttpContextBase>();
    var lWindowsIdentity = new WindowsIdentity("Administrator");

    httpContextMock.Setup(x => x.User).Returns(new WindowsPrincipal(lWindowsIdentity));

    contextMock.Setup(ctx => ctx.HttpContext).Returns(httpContextMock.Object);
    myController.ControllerContext = contextMock.Object;

    // Act
    var lResult = myController.Index() as ViewResult;

    // Assert
    Assert.IsTrue(lResult.ViewBag.Username == "Administrator");
    Assert.IsTrue(lResult.ViewBag.Sid == "Any SID Pattern");
}
5
Simon

特定のユーザーを強制するためにFormsAuthを使用するために、開発環境global.asaxとWeb.Configを変更しました。ユーザー名は同じWindowsAuth形式を使用します。見る:

public override void Init()
    {
        base.Init();

        this.PostAuthenticateRequest += 
             new EventHandler(MvcApplication_PostAuthenticateRequest);
    }

    void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
    {
        FormsAuthentication.SetAuthCookie("Domain\\login", true);
    }

Windowsまたはフォーム認証は同じログインパターンを共有します

アプリケーションは、Windows認証とフォーム認証の両方で動作します。

1
Marcos Lima

WindowsIdentityをモックするには、次のようにします。

var mockedPrincipal = new Mock<WindowsPrincipal>(WindowsIdentity.GetCurrent());

mockedPrincipal.SetupGet(x => x.Identity.IsAuthenticated).Returns(true);
mockedPrincipal.SetupGet(x => x.Identity.Name).Returns("Domain\\User1");
mockedPrincipal.Setup(x => x.IsInRole("Domain\\Group1")).Returns(true);
mockedPrincipal.Setup(x => x.IsInRole("Domain\\Group2")).Returns(false);

次にmockedPrincipal.Objectを使用して実際のWindowsIdentityを取得します

0
Assaf S.