2016-05-16 60 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

相關問題