Mock IIdentity and IPrincipal

无人久伴 提交于 2019-12-04 11:24:57

问题


I just wanna ask what would be better approach to supply these objects in my unit tests.

In my unit test I am testing CSLA object. CSLA object is internally using one property and one method of ApplicationUser object. ApplicationUser is inherited from IPrincipal. The properties are: 1) ApplicationContext.User.IsInRole(...) - the method is part of IPrincipal 2) ApplicationContext.User.Identity.Name - the name is property of IIdentity which is part of ApplicationUser aka IPricipal

Example of my test (using RhinoMock):

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);
      Expect.Call(mockPrincipal.Identity.Name).Return("ju"); //doesn't work!!!! return null ref exc
   }
}

I have slight problem with second value, the identity name. I tried to mock it but have problem to assign mocked IIdentity to ApplicationUser, as it is done internaly. I was told to just create some IIPrincipal (including IIdentity) by myself and not to mock it at all. Which can be done for sure. Not sure if this can be called as Stub using?

So can you advice me how to deal with IPrincipal and IIdentity? Any suggestion most welcome.


回答1:


The reason you're getting a null reference error is because IPrincipal.Identity is null; it hasn't been set in your mocked IPrincipal yet. Calling .Name the null Identity results in your exception.

The answer, as Carlton pointed out, is to mock IIdentity also, and set it up to return "ju" for its Name property. Then you can tell IPrincipal.Identity to return the mock IIdentity.

Here is an expansion of your code to do this (using Rhino Mocks rather than Stubs):

public void BeforeTest()
{
   mocks = new MockRepository();
   IPrincipal mockPrincipal = mocks.CreateMock<IPrincipal>();
   IIdentity mockIdentity = mocks.CreateMock<IIdentity>();
   ApplicationContext.User = mockPrincipal;
   using (mocks.Record()) 
   {
      Expect.Call(mockPrincipal.IsInRole(Roles.ROLE_MAN_PERSON)).Return(true);
      Expect.Call(mockIdentity.Name).Return("ju"); 
      Expect.Call(mockPrincipal.Identity).Return(mockIdentity);
   }
}



回答2:


Here is the code I use to return a test user (using Stubs):

    [SetUp]
    public void Setup()
    {
        var identity = MockRepository.GenerateStub<IIdentity>();
        identity.Stub(p => p.Name).Return("TestUser").Repeat.Any();
        var principal = MockRepository.GenerateStub<IPrincipal>();
        principal.Stub(p => p.Identity).Return(identity).Repeat.Any();

        Thread.CurrentPrincipal = principal;
    }

I've got linq in other code so I'm using the var type for the variables; just substitute the correct types (IPrincipal, IIdentity) if needed.



来源:https://stackoverflow.com/questions/162534/mock-iidentity-and-iprincipal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!