Is there a easy way to Mock IIdentity.GetUserId and IIdentity.IsAuthenticated?
I've tested this way and got a NotSupportedException .
[Test]
public void CanGetUserIdFromIdentityTest()
{
//Enviroment
var mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(x => x.Name).Returns("test@test.com");
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);
}
I've tested using GenericIdentity too. Using that i can mock GetUserId() , but i can't mock IsAuthenticated property.
Anyone can help me?
You get the NotSupportedException
because GetUserId
is an extension method from IdentityExtensions.GetUserId Method and does not belong to the mocked object. There is no need to mock GetUserId
.
If you look at the source code for GetUserId
you will see what it is not working for you.
/// <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;
}
}
It is looking for a ClaimsIdentity
with a ClaimTypes.NameIdentifier
, which it why it worked for GenericIdentity
. So that mean that you would need to create a stub of the Identity. In order to get IsAuthenticated
to work you just need to provide an authentication Type in the constructor. An empty string will work.
Here is your test method with the changes
[Test]
public void Should_GetUserId_From_Identity() {
//Arrange
var username = "test@test.com";
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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.