views:

189

answers:

1

As part of a unit test I am trying to mock the return value of FormsIdentity.Ticket.UserData

The following will NOT work but it should give an idea of what I am trying to do:

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);

The code I am trying to test looks something like this:

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

All I want to do in my unit test is fake the return value from FormsIdentity.Ticket.UserData. But when I run the code in the first section I get an error when trying to mock the FormsIdentity. The error says the type to mock must be an interface, abstract class or non-sealed class.

I tried to use IIdentity instead of FormsIdentity (FormsIdentity is an implementation of IIdentity) but IIdentity doesn't have .Ticket.UserData.

So how can I write this test so that I get a value from FormsIdentity.Ticket.UserData?

A: 

I'm not a Unit Test expert, by any means, just getting my feet wet in the area.

Isn't it overkill to mock out the Identity in a unit test, because the Identity code is code that you can assume works already in isolation? (ie. it's Microsoft's code?) For example, when unit testing your own code, you wouldn't need to mock out one of the Framework objects. I mean, would you ever need to mock a List or a Dictionary?

That being said, if you REALLY want to test your code in isolation or for some reason have super fine control over the data returned in Userdata, can't you just write an Interface for the interaction between the Identity and your code?

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

Hope this helps

XDecker
My fault for trying to keep the question succinct. But this will not work for me since the Principal identity is being accessed inside the method I am trying to test. But you are correct that I am not testing the right part of my method
codette