【问题标题】:Mock IIdentity and IPrincipal模拟 Iidentity 和 IPrincipal
【发布时间】:2023-04-08 07:46:01
【问题描述】:

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

在我的单元测试中,我正在测试 CSLA 对象。 CSLA 对象在内部使用 ApplicationUser 对象的一种属性和一种方法。 ApplicationUser 继承自 IPrincipal。 属性是: 1) ApplicationContext.User.IsInRole(...) - 该方法是 IPrincipal 的一部分 2) ApplicationContext.User.Identity.Name - 名称是 IIdentity 的属性,它是 ApplicationUser aka 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),根本不要嘲笑它。这是肯定可以做到的。不确定这是否可以称为存根使用?

那么你能建议我如何处理 IPrincipal 和 IIdentity 吗?欢迎提出任何建议。

【问题讨论】:

    标签: mocking iprincipal


    【解决方案1】:

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

    正如 Carlton 指出的那样,答案是模拟 IIdentity also,并将其设置为为其 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);
       }
    }
    

    【讨论】:

    • CreateMock 已被弃用。请改用StrictMockDynamicMock
    【解决方案2】:

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

        [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)即可。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 2017-09-06
      • 2011-11-03
      • 2012-05-31
      • 2015-10-07
      • 2015-01-22
      • 2012-01-05
      • 2010-11-07
      相关资源
      最近更新 更多