Одно быстрое примечание, прежде чем я прыгнуть в это. Как правило, вы хотите избежать использования «Строгого» макета, потому что это делает хрупкий тест. Строгий макет будет генерировать исключение, если что-то случится, что вы явно не сообщите, что Rhino произойдет. Также я думаю, что вы можете неправильно понимать, что делает Rhino, когда вы делаете звонок, чтобы создать макет. Подумайте об этом как о пользовательском объекте, который был либо получен, либо реализует определенный вами System.Type. Если вы сделали это сами, это будет выглядеть так:
public class FakeUserType: User
{
//overriding code here
}
С IsAdministrator, вероятно, просто общественная собственность на тип пользователя вы не можете изменить его в тип наследуемым.
Что касается вашего вопроса, есть несколько способов справиться с этим. Вы могли бы реализовать IsAdministrator в качестве виртуальной собственности на вашем пользовательском классе, как aaronjensen упоминается следующим образом:
public class User
{
public virtual Boolean IsAdministrator { get; set; }
}
Это нормально подход, но только если вы планируете наследовать от вашего класса User. Кроме того, если вы не подделываете других участников этого класса, они также должны быть виртуальными, что, вероятно, не является желаемым поведением.
Другой способ добиться этого - использование интерфейсов. Если это действительно класс пользователя, который вы хотите выполнить Mock, я бы извлек из него интерфейс. Ваш приведенный выше пример будет выглядеть примерно так:
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
}
Вы можете получить новые идеи, если вы хотите с помощью dependency injection and IOC но основной принцип остается тем же по всем направлениям. Как правило, вы хотите, чтобы ваши классы зависели от интерфейсов, а не от конкретных реализаций.
Надеюсь, это поможет. Я давно использую RhinoMocks в крупном проекте, поэтому не стесняйтесь задавать мне вопросы о TDD и насмехаться.
Просто обратите внимание, что этот последний пример требует `_mocks.ReplayAll()` прежде чем вы что-нибудь сделаете с заглушкой IUser. – 2009-10-30 00:07:11