2009-10-09 6 views
6

В рамках модульного тестирования Я пытаюсь издеваться возвращаемым значением FormsIdentity.Ticket.UserDataMocking FormsIdentity.Ticket.UserData с Moq

Следующие НЕ будет работать, но он должен дать представление о том, что я пытаясь сделать:

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.Ti cket.UserData. Но когда я запускаю код в первом разделе, я получаю сообщение об ошибке при попытке издеваться над FormsIdentity. Ошибка говорит, что тип moker должен быть интерфейсом, абстрактным классом или незапечатанным классом.

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

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

+0

Оказываются, метод, который я пытался тест делал слишком много. Это нарушало шаблон единой ответственности, который затруднял проверку. У меня с тех пор был реорганизован метод. Что касается оригинального вопроса - не существует никакого способа издеваться над FormsIdentity.Ticket.UserData, поскольку он является частью закрытого класса. – codette

ответ

0

Я не эксперт по анализу единиц, каким бы то ни было образом, просто мокрые ноги в этом районе.

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

Надеется, что это помогает

+0

. Моя ошибка в попытке сохранить этот вопрос кратким. Но это не сработает для меня, так как идентификатор Principal доступен в методе, который я пытаюсь проверить. Но вы правы, что я не тестирую правильную часть моего метода – codette

Смежные вопросы