2016-05-16 59 views
1

有没有简单的方法来模拟IIdentity.GetUserId和IIdentity.IsAuthenticated?如何模拟GetUserId和IsAuthenticated从IIdentity没有ControllerContext

我测试过这种方式,得到了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属性。

任何人都可以帮到我吗?

回答

2

你得到NotSupportedException因为GetUserIdIdentityExtensions.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; 
    } 
} 

它寻找一个ClaimsIdentityClaimTypes.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); 
} 
+0

它的工作原理!我使用空字符串作为参数实例化GenericIdentity。 真的很感谢你。 –

+1

很高兴帮助。如果您发现这个答案有用,请对它投票。如果此答案可解决您的问题,请将其标记为已回答。谢谢。快乐编码! – Nkosi

相关问题