РиноМоксы:Правильный способ издеваться над методом получения свойств

StackOverflow https://stackoverflow.com/questions/78389

  •  09-06-2019
  •  | 
  •  

Вопрос

Я новичок в RhinoMocks и пытаюсь разобраться в синтаксисе, а также в том, что происходит под капотом.

У меня есть объект пользователя, назовем его User, у которого есть свойство IsAdministrator.Значение IsAdministrator оценивается с помощью другого класса, который проверяет разрешения безопасности пользователя и возвращает либо true, либо false в зависимости от этих разрешений.Я пытаюсь высмеять этот класс User и подделать возвращаемое значение для IsAdministrator, чтобы изолировать некоторые модульные тесты.

Это то, что я делаю до сих пор:

public void CreateSomethingIfUserHasAdminPermissions()
{
    User user = _mocks.StrictMock<User>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
} 

Теперь я ожидаю, что Rhino «подделает» вызов средству получения свойств и просто вернет мне true.Это неправильно?В настоящее время я получаю исключение из-за зависимостей в свойстве IsAdministrator.

Может ли кто-нибудь объяснить, как я могу достичь своей цели здесь?

Это было полезно?

Решение

Одно небольшое замечание, прежде чем я перейду к этому.Обычно лучше избегать использования «строгого» макета, поскольку он делает тест ненадежным.Строгий макет выдаст исключение, если произойдет что-то, о чем вы явно не сообщите Rhino.Также я думаю, что вы, возможно, неправильно понимаете, что именно делает Rhino, когда вы вызываете создание макета.Думайте об этом как о пользовательском объекте, который либо был получен из определенного вами System.Type, либо реализовал его.Если бы вы сделали это сами, это выглядело бы так:

public class FakeUserType: User
{
    //overriding code here
}

Поскольку IsAdministrator, вероятно, является общедоступным свойством типа User, вы не можете переопределить его в наследующем типе.

Что касается вашего вопроса, есть несколько способов справиться с этим.Вы можете реализовать IsAdministrator как виртуальное свойство вашего пользовательского класса как Аарондженсен упоминается следующим образом:

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 и насмешках.

Другие советы

Убедитесь, что IsAdministrator является виртуальным.

Кроме того, обязательно вызовите _mocks.ReplayAll().

_mocks.ReplayAll() ничего не сделает.Только потому, что вы используете SetupResult.For(), это не учитывается.Используйте Expect.Call(), чтобы убедиться, что ваш код все делает правильно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top