有没有一种简单的方法可以模拟IIdentity.GetUserId和IIdentity.IsAuthenticated?
我已经测试了这种方式,并得到了NotSupportedException。
[Test]
public void CanGetUserIdFromIdentityTest()
{
//Enviroment
var mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(x => x.Name).Returns("[email protected]");
mockIdentity.Setup(x => x.IsAuthenticated).Returns(true);
mockIdentity.Setup(x => x.GetUserId()).Returns("12345");
var mockPrincipal = new Mock<IPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(mockIdentity.Object);
mockPrincipal.Setup(x => x.IsInRole(It.IsAny<string>())).Returns(true);
//Action
Kernel.Rebind<IPrincipal>().ToConstant(mockPrincipal.Object);
//Asserts
var principal = Kernel.Get<IPrincipal>();
Assert.IsNotNull(principal.Identity.GetUserId());
Assert.IsTrue(principal.Identity.IsAuthenticated);
}
我也使用GenericIdentity进行了测试。使用它,我可以模拟GetUserId(),但不能模拟IsAuthenticated属性。
有人可以帮助我吗?
最佳答案
您获得NotSupportedException
,因为GetUserId
是IdentityExtensions.GetUserId Method的扩展方法,并且不属于模拟对象。无需模拟GetUserId
。
如果您查看GetUserId
的源代码,您会发现它不适用于您。
/// <summary>
/// Extensions making it easier to get the user name/user id claims off of an identity
/// </summary>
public static class IdentityExtensions
{
/// <summary>
/// Return the user name using the UserNameClaimType
/// </summary>
/// <param name="identity"></param>
/// <returns></returns>
public static string GetUserName(this IIdentity identity)
{
if (identity == null)
{
throw new ArgumentNullException("identity");
}
var ci = identity as ClaimsIdentity;
if (ci != null)
{
return ci.FindFirstValue(ClaimsIdentity.DefaultNameClaimType);
}
return null;
}
/// <summary>
/// Return the user id using the UserIdClaimType
/// </summary>
/// <param name="identity"></param>
/// <returns></returns>
public static string GetUserId(this IIdentity identity)
{
if (identity == null)
{
throw new ArgumentNullException("identity");
}
var ci = identity as ClaimsIdentity;
if (ci != null)
{
return ci.FindFirstValue(ClaimTypes.NameIdentifier);
}
return null;
}
/// <summary>
/// Return the claim value for the first claim with the specified type if it exists, null otherwise
/// </summary>
/// <param name="identity"></param>
/// <param name="claimType"></param>
/// <returns></returns>
public static string FindFirstValue(this ClaimsIdentity identity, string claimType)
{
if (identity == null)
{
throw new ArgumentNullException("identity");
}
var claim = identity.FindFirst(claimType);
return claim != null ? claim.Value : null;
}
}
它正在寻找带有
ClaimsIdentity
的ClaimTypes.NameIdentifier
,这就是为什么它适用于GenericIdentity
的原因。因此,这意味着您需要创建身份的存根。为了使IsAuthenticated
工作,您只需要在构造函数中提供一个身份验证类型即可。空字符串将起作用。这是您所做的更改的测试方法
[Test]
public void Should_GetUserId_From_Identity() {
//Arrange
var username = "[email protected]";
var identity = new GenericIdentity(username, "");
var nameIdentifierClaim = new Claim(ClaimTypes.NameIdentifier, username);
identity.AddClaim(nameIdentifierClaim);
var mockPrincipal = new Mock<IPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity);
mockPrincipal.Setup(x => x.IsInRole(It.IsAny<string>())).Returns(true);
Kernel.Rebind<IPrincipal>().ToConstant(mockPrincipal.Object);
//Act
var principal = Kernel.Get<IPrincipal>();
//Asserts
Assert.AreEqual(username, principal.Identity.GetUserId());
Assert.IsTrue(principal.Identity.IsAuthenticated);
}
关于c# - 如何在没有ControllerContext的情况下从IIdentity模拟GetUserId和IsAuthenticated,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37264994/