Mocking FormsIdentity.Ticket.UserData с Moq - PullRequest
       17

Mocking FormsIdentity.Ticket.UserData с Moq

6 голосов
/ 10 октября 2009

В рамках модульного теста я пытаюсь смоделировать возвращаемое значение 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. В сообщении об ошибке указывается, что тип для имитации должен быть интерфейсом, абстрактным классом или незапечатанным классом.

Я пытался использовать IIdentity вместо FormsIdentity (FormsIdentity является реализацией IIdentity), но у IIdentity нет .Ticket.UserData.

Итак, как мне написать этот тест, чтобы получить значение из FormsIdentity.Ticket.UserData?

1 Ответ

0 голосов
/ 10 октября 2009

Я ни в коем случае не эксперт по юнит тестам, просто промокаю ноги в этом районе.

Разве не излишне копировать Identity в модульном тесте, потому что Identity code - это код, который, как вы можете полагать, работает уже изолированно? (т.е. это код 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

Надеюсь, это поможет

...