模拟身份和IPrincipal

时间:2020-03-06 15:01:42  来源:igfitidea点击:

我只想问问在单元测试中提供这些对象的更好方法是什么。

在单元测试中,我正在测试CSLA对象。 CSLA对象在内部使用ApplicationUser对象的一种属性和一种方法。 ApplicationUser继承自IPrincipal。
这些属性是:
1)ApplicationContext.User.IsInRole(...)该方法是IPrincipal的一部分
2)ApplicationContext.User.Identity.Name的名称是IIdentity的属性,IIdentity是ApplicationUser的一部分,也称为IPricipal

我的测试示例(使用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
   }
}

我对第二个值(身份名称)有轻微的问题。我尝试模拟它,但是在内部完成时很难将模拟的IIdentity分配给ApplicationUser。
有人告诉我我自己创建一些IIPrincipal(包括IIdentity),而不要完全嘲笑它。可以肯定地做到这一点。不确定是否可以将其称为Stub使用?

那么,我们能建议我如何处理IPrincipal和IIdentity吗?任何建议最欢迎。

解决方案

这是我用来返回测试用户(使用存根)的代码:

[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;
    }

我在其他代码中使用了linq,因此我将var类型用作变量;只需根据需要替换正确的类型(IPrincipal,IIdentity)。

出现空引用错误的原因是因为IPrincipal.Identity为空。尚未在我们模拟的" IPrincipal"中设置它。调用.Name为空的Identity会导致异常。

正如卡尔顿指出的那样,答案是还要模拟" IIdentity",并将其设置为为其" Name"属性返回" ju"。然后,我们可以告诉IPrincipal.Identity返回模拟IIdentity

这是执行此操作的代码扩展(使用Rhino Mocks而不是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);
   }
}