【问题标题】:Mock My.User.IsInRole() and ClaimsPrincipal in Asp.Net MVC在 Asp.Net MVC 中模拟 My.User.IsInRole() 和 ClaimsPrincipal
【发布时间】:2018-05-02 14:14:38
【问题描述】:

我有一个单元测试来模拟以下控制器中的 My.User.IsInRole() 和 ClaimsPrincipal。

当前线程原理已经被分配了两次,因此只有第二个 ClaimPrincipal 在工作,我该怎么做才能让两个模拟原理都工作?

Public Class TestController
   Public Function GetUserDetail() As String
       If My.User.IsInRole("Agent") Then
           result = "Login as Agent"
       End If

       If ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value = "user@hotmail.com" Then
           result = result & " and Claim name is correct"
       End If

       Return result
   End Function
End Class

尝试在这个测试用例中设置 mock(VB 代码,C# 也可以):

<TestMethod()>
 Public Sub Test()
    //Arrange

    //Mock User.IsInRole():
    Dim fakePrincipal = New Moq.Mock(Of IPrincipal)()
    fakePrincipal.Setup(Function(p) p.IsInRole("Agent")).Returns(True)
    Thread.CurrentPrincipal = fakePrincipal.[Object]

    'Dim fakeClaimPrincipal = New Mock(Of ClaimsPrincipal)()
    'Dim claims As IEnumerable(Of Claim) = New List(Of Claim) ().AsEnumerable()
    'fakeClaimPrincipal.Setup(Sub(e) e.Claims).Returns(claims)
    'Thread.CurrentPrincipal = fakeClaimPrincipal.[Object]

    //Mocking is not working on ClaimsPrincipal.FindFirst(), so it's fixed 
      by using claim based function:

    Thread.CurrentPrincipal = New TestPrincipal(New Claim(ClaimTypes.Name, "user@hotmail.com"))

    Public Class TestPrincipal
        Inherits ClaimsPrincipal
        Public Sub New(ParamArray claims As Claim())
               MyBase.New(New TestIdentity(claims))
        End Sub
    End Class

    Public Class TestIdentity
         Inherits ClaimsIdentity
         Public Sub New(ParamArray claims As Claim())
                MyBase.New(claims)
         End Sub
    End Class

   // Act
   Dim result = TestController.GetUserDetail()

 End Sub

那么一个是mock principal,一个不是mock principal,如何分配当前线程?

【问题讨论】:

标签: asp.net asp.net-mvc vb.net unit-testing moq


【解决方案1】:

第二个模拟覆盖了在线程上设置的第一个模拟。

使用模拟的ClaimsPrincipal 并设置必要的成员

<TestMethod()>
Public Sub Test()
    //Arrange    
    Dim fackClaimPrinciple = New Mock(Of ClaimsPrincipal)()        
    Dim claims As IEnumerable(Of Claim) = New List(Of Claim) ().AsEnumerable()
    fackClaimPrinciple.Setup(Sub(e) e.Claims).Returns(claims)
    fackClaimPrinciple.Setup(Function(p) p.IsInRole("Agent")).Returns(True)
    Thread.CurrentPrincipal = fackClaimPrinciple.[Object]

   // Act
   Dim result = TestController.GetUserDetail()

 End Sub

【讨论】:

  • 在这种情况下最好使用一个主体。看我上面的代码改动,一个是mock principal,一个不是mock principal,能不能用一个principal分配给当前线程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 2016-11-14
  • 2018-10-06
  • 2010-10-22
  • 1970-01-01
相关资源
最近更新 更多