Mocking IIdentity

Mocking IIdentity

Old forum URL: forums.lhotka.net/forums/t/5492.aspx


Xabatcha posted on Monday, September 29, 2008

HI All,
    has anyone experiences with mocking ApplicationContext.User alias IIdentity?
I am using ApplicationContext.User like this:
      public override ContactItem Save()
      {
         _updatedBy = ApplicationContext.User.Identity.Name;
         return base.Save();
      }


and related test class
looks like this: (I am using RhinoMock)
   [TestFixture]
   public class TContact {
      private string user = "someuser";
      private Guid _id = Guid.Empty;
      private MockRepository mocks;

      [SetUp]
      public void BeforeTest()
      {
         mocks = new MockRepository();
         IPrincipal mockPrincipal = mocks.CreateMock<IPrincipal>();
         ApplicationContext.User = mockPrincipal;

         using (mocks.Record()) {
            Expect.Call(mockPrincipal.IsInRole(Roles.ROLE_MAN_PERSON)).Return(true);
         }
      }

      [Test]
      public void T1ItemInsert()
      {
         ContactItem item = null;

         using (mocks.Playback()) {
            item = ContactItem.NewContactItem();
         }
         _id = item.Id;
         item.FirstName = "Igor";
         item.LastName = "Tudor";
         item.NickName = "Ig";
         item.Notes = "bla bla bla";

         Assert.IsNotNull(item);
         Assert.IsTrue(item.IsNew);
         Assert.IsTrue(item.IsDirty);

         item.Save();

         Assert.IsNotNull(item);
         Assert.IsFalse(item.IsNew);
         Assert.IsFalse(item.IsDirty);
      }
}

Could someone point me how I can mock the ApplicationUser alias IIdentity object? Any tip most welcome. Thanks in advance.

BTW: At this moment I avoid to mock any DAO objects and let sql server doing its work. Besides the fact that most of people don't recommend to mock DAO objects.

JonStonecash replied on Tuesday, September 30, 2008

I am confused.  It appears that you are already mocking the IIdentity object in CSLA.Application.Context.User.  Are you looking for another way of doing this?  Is the current way not working?  If so, what is not working?

I just did a blog entry on this very topic: http://blog.magenic.com/blogs/jons/archive/2008/09/25/Spoofing-the-CSLA-Identity-and-Principal.aspx

This might be of some help.

Jon Stonecash

Xabatcha replied on Tuesday, September 30, 2008

Sorry to confuse you...I may adding a bit of explanation as some info is missing.

In BeforeTest method I mock IPrincipal object. I call IsInRole method in my BO in Autorization method (eg. CanAddObject()).  The fake result is substitute at line #7.

In Save method of my BO I read ApplicationContext.User.Identity.Name value. I tried to put this piece of code ( Expect.Call(mockPrincipal.Identity.Name).Return("ju"); ) after line #7, but it gave me an error. (Null reference, I guess because the IIdentity is not created)

I just suppose I need to mock IIdentity object and add the reference to ApplicationContext in same way.

     #1  public void BeforeTest()
     #2 {
     #3    mocks = new MockRepository();
     #4   IPrincipal mockPrincipal = mocks.CreateMock<IPrincipal>();
     #5    ApplicationContext.User = mockPrincipal;
     #6    using (mocks.Record()) {
     #7       Expect.Call(mockPrincipal.IsInRole(Roles.ROLE_MAN_PERSON)).Return(true);
     #8    }
     #9 }

That's a bit more for decription. Thanks for any helps.

JonStonecash replied on Thursday, October 02, 2008

Ah ha!  My problem is that I did not take a close enough look at the code.  At least one of your problems is in deed that you did not mock the IIdentity object.  The specific line in question is:

       _updatedBy = ApplicationContext.User.Identity.Name;

This is going through the IPrincipal object in ApplicationContext.User to get the IIdentity object and then trying to get the name from the the IIdentity object.  The IIdentity object is null in this context and you end up with a null reference exception. 

You need to mock the IIdentity object and specifically the Name property on that interface.  You can use something like RhinoMocks for that but I would suggest that you write a dummy TestPrincipal and TestIdentity.  The test versions of these classes are very simple and most CSLA classes typically have a fair amount of authorization-based behavior that is controlled by the behavior of the IPrincipal and IIdentity objects.  I find it easier to create stubs that I can control than to repeat the mocking logic each time.  But you do what makes sense for you.

Jon Stonecash

Copyright (c) Marimer LLC