使用Moq模拟FormsIdentity.Ticket.UserData

时间:2009-10-09 22:55:45

标签: asp.net-mvc tdd mocking moq

作为单元测试的一部分,我试图模拟FormsIdentity.Ticket.UserData的返回值

以下内容不起作用,但它应该让我知道我想要做什么:

var principal = Mock<IPrincipal>();
var formsIdentity = Mock<FormsIdentity>();
formsIdentity.Setup(a => a.Ticket.UserData).Returns("aaa | bbb | ccc");
principal.Setup(b => b.Identity).Returns(formsIdentity.Object);

我试图测试的代码看起来像这样:

FormsIdentity fIdentity = HttpContext.Current.User.Identity as FormsIdentity;
string userData = fIdentity.Ticket.UserData;

我想在单元测试中做的就是伪造FormsIdentity.Ticket.UserData的返回值。但是当我在第一部分运行代码时,我在尝试模拟FormsIdentity时遇到错误。错误说mock的类型必须是接口,抽象类或非密封类。

我尝试使用IIdentity而不是FormsIdentity(FormsIdentity是IIdentity的实现)但是IIdentity没有.Ticket.UserData。

那么如何编写此测试以便从FormsIdentity.Ticket.UserData获取值?

1 个答案:

答案 0 :(得分:0)

我不是单位测试专家,无论如何,只是让我的脚在该区域湿润。

在单元测试中嘲笑身份是不是太过分了,因为身份代码是您可以假设已经孤立的代码? (即它是Microsoft的代码吗?)例如,在对您自己的代码进行单元测试时,您不需要模拟其中一个Framework对象。我的意思是,你是否需要模拟一个列表或一个字典?

话虽如此,如果您真的想要单独测试代码或出于某种原因对Userdata中返回的数据进行超级精细控制,那么您是否只能为Identity和代码之间的交互编写一个接口?

Public Interface IIdentityUserData
   Readonly Property UserData As String
End Interface

Public Class RealIdentityWrapper 
 Implements IIdentityUserData

Private _identity as FormsIdentity
Public Sub New(identity as FormsIdentity)
    'the real version takes in the actual forms identity object
    _identity = identity
End Sub
Readonly Property UserData As String Implements IIDentityUserData.UserData
     If not _identity is nothing then
         Return _identity.Ticket.UserData
     End If
End Property
End Class

 'FAKE CLASS...use this instead of Mock
 Public Class FakeIdentityWrapper 
 Implements IIdentityUserData


 Readonly Property UserData As String Implements IIDentityUserData.UserData
     If not _identity is nothing then
          Return "whatever string you want"
     End If
 End Property
 End Class



'here's the code that you're trying to test...modified slightly
 Dim fIdentity As FormsIdentity= HttpContext.Current.User.Identity
 Dim identityUserData As IIdentityUserData

 identityUserData = 
 'TODO: Either the Real or Fake implementation. If testing, inject  the Fake implementation. If in production, inject the Real implementation

 Dim userData as String
 userData = identityUserData.UserData

希望这有帮助