10

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

在我的单元测试中,我正在测试 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 吗?任何建议都非常受欢迎。

4

2 回答 2

10

你得到一个空引用错误的原因是因为IPrincipal.Identity是空的;它还没有设置在你的嘲笑中IPrincipal。调用.NamenullIdentity会导致您的异常。

正如卡尔顿指出的那样,答案是也模拟IIdentity 并将其设置为为其Name属性返回“ju”。然后你可以告诉IPrincipal.Identity返回 mock 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);
   }
}
于 2009-07-07T17:53:59.697 回答
4

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

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

于 2008-10-02T14:39:48.363 回答