在我开始之前先做一个简短的说明。通常,您希望避免使用“严格”模拟,因为它会导致脆弱的测试。如果发生任何您没有明确告诉 Rhino 会发生的事情,严格的模拟将抛出异常。此外,我认为您在调用创建模拟时可能会误解 Rhino 正在做什么。将其视为一个自定义对象,该对象要么派生自,要么实现了您定义的 System.Type。如果你自己做,它看起来像这样:
public class FakeUserType: User
{
//overriding code here
}
由于 IsAdministrator 可能只是 User 类型的公共属性,因此您不能在继承类型中覆盖它。
就您的问题而言,您可以通过多种方式处理此问题。您可以将 IsAdministrator 实现为您的用户类上的虚拟属性,如下所述的aaronjensen :
public class User
{
public virtual Boolean IsAdministrator { get; set; }
}
这是一个不错的方法,但前提是您计划从您的 User 类继承。此外,如果您不想伪造此类上的其他成员,他们也必须是虚拟的,这可能不是所需的行为。
实现此目的的另一种方法是使用接口。如果它确实是您想要模拟的 User 类,那么我会从中提取一个接口。你上面的例子看起来像这样:
public interface IUser
{
Boolean IsAdministrator { get; }
}
public class User : IUser
{
private UserSecurity _userSecurity = new UserSecurity();
public Boolean IsAdministrator
{
get { return _userSecurity.HasAccess("AdminPermissions"); }
}
}
public void CreateSomethingIfUserHasAdminPermissions()
{
IUser user = _mocks.StrictMock<IUser>();
SetupResult.For(user.IsAdministrator).Return(true);
// do something with my User object
}
如果你愿意,你可以通过使用依赖注入和 IOC来获得更好的体验,但基本原理是相同的。通常,您希望您的类依赖于接口而不是具体的实现。
我希望这有帮助。我在一个主要项目中使用 RhinoMocks 已经有很长时间了,所以请不要犹豫,向我询问有关 TDD 和 mocking 的问题。