如何在ASP MVC 5(Microsoft.AspNet.Identity)中存根User.Identity.GetU



如何在ASPMVC 5(Microsoft.AspNet.Identity)中存根User.Identity.GetUserId()以进行MVC5控制器的单元测试?GetUserId()是一个扩展,所以我不能直接嘲笑它。我需要在测试前分配Id。似乎您必须创建一个Claim并将其分配给GenericIdentity。但是对于一个单元测试来说似乎有很多事情要做。你知道其他选择吗?

非常感谢您的想法。我使用的是NSubstitute。我既没有Microsoft Fakes也没有JustLock。因此,我结束了直接向GenericIdentity填充声明,这样我就可以控制UserId:的值

string username = "username";
string userid = Guid.NewGuid().ToString("N"); //could be a constant
List<Claim> claims = new List<Claim>{
    new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", username), 
    new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userid)
};
var genericIdentity = new GenericIdentity("");
genericIdentity.AddClaims(claims);
var genericPrincipal = new GenericPrincipal(genericIdentity, new string[] { "Asegurado" });
controllerContext.HttpContext.User = genericPrincipal;

准备好承受疼痛了吗?

这将在很大程度上取决于您使用的是哪种嘲讽框架。根据我的假设,你正在使用Moq,那么你就有点运气不好了,因为Moq在这方面做得不好。原因是Moq不能模拟扩展方法(实际上它可以,但你不想/不应该想这样做:-)

如果你正在使用另一个类似JustLock的嘲讽框架,那么你的里程数可能会有所不同。根据这一点,这是一个该死的景象比什么更容易遵循。

我发现的最简单的方法(仍然很不容易)是使用Microsoft Fakes

大多数新的标识内容都是使用扩展接口编写的。我一辈子都不明白为什么他们认为这是个好主意,但你来了。

以下是你需要做的。

首先为Microsoft.AspNet.Identity创建一个Fake程序集。您可以通过右键单击程序集并选择"添加伪造程序集"来完成此操作。这基本上是在组件中行走,并为它在那里找到的所有东西创建垫片和存根。您要做的是填充对GetUserId的调用,。。实际上这并不难。

然后,你必须对ControllerContext进行常规的嘲讽,因为它的声音很熟悉。

下面的代码将做你正在寻找的我认为-

        using (var context = ShimsContext.Create())
        {
            Microsoft.AspNet.Identity.Fakes
                .ShimIdentityExtensions.GetUserIdIIdentity =
            (i) => "Mr. T";
            var fakeHttpContext = new Mock<HttpContextBase>();
            var fakeIdentity = new GenericIdentity("User");
            var principal = new GenericPrincipal(fakeIdentity, null);
            fakeHttpContext.Setup(t => t.User).Returns(principal);
            var controllerContext = new Mock<ControllerContext>();
            controllerContext.Setup(t => t.HttpContext)
                .Returns(fakeHttpContext.Object);
            var sut = new HomeController();
            sut.ControllerContext = controllerContext.Object;
            var result = sut.YourTestAction();
            Assert.True(result.WhatYouCareAbout);
        }

当然,不一定是t.先生

HTH

您可以创建从MvcContrib.TestHelper.Fakes 中的对象继承的伪主体和/或标识

然后你可以做这样的事情:

        using (var userManager = _userManagerFactory.CreateUserManager())
        {
            var userId = Guid.NewGuid().ToString();
            var result = userManager.CreateAsync(new IdentityUser() { Id = userId, UserName = "userName" }, "password").Result;
            Assert.IsTrue(result.Succeeded, "failed to create user through usermanager");
            var fakePrincipal = new FakePrincipal(new FakeClaimIdentity(userId, "userName"), new[] { "SomeRole" });
            Assert.IsTrue(fakePrincipal.Identity.IsAuthenticated, "fake user did not come back authenticated");
        }

我用来制作虚假声明身份的类是:

using System.Collections.Generic;
using System.Security.Claims;
using MvcContrib.TestHelper.Fakes;
namespace Tests.Unit.Fakes
{
    public class FakeClaimIdentity : ClaimsIdentity
    {
        private readonly FakeIdentity _fakeIdentity;

        public FakeClaimIdentity(string id, string userName) : base(userName)
        {
            _fakeIdentity = new FakeIdentity(userName);
            base.AddClaims(new List<Claim>
            {
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", userName),
                new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", id)
            });
        }
        public override bool IsAuthenticated
        {
            get { return _fakeIdentity.IsAuthenticated; }
        }
        public override string Name
        {
            get { return _fakeIdentity.Name; }
        }
        public override string AuthenticationType
        {
            get
            {
                return _fakeIdentity.AuthenticationType;
            }
        }
    }
}

通过这种方式,还可以测试IsAuthenticated部分(如果您关心身份的有效性)。

相关内容

  • 没有找到相关文章

最新更新