помощь в тестировании абстрактного метода с помощью моков носорога

Я хочу написать несколько модульных тестов для своего класса C #. У меня есть базовый класс BaseClass, в котором есть абстрактный метод Execute, а также метод Redirect. У меня есть класс Class1, который наследует BaseClass и реализует абстрактный метод Execute, метод, который я хочу протестировать. Следующий код объясняет дальнейшую настройку:

public abstract class BaseClass
{
    public abstract void Execute();

    public void Redirect()
    {
        // redirect code here
    }
}

public class Class1 : BaseClass
{
    public void Execute()
    {
      // do some processing

      this.Redirect();
    }
}

Я работаю с mstest и использую насмешки для носорогов. Я хочу написать тесты для Execute метода, чтобы проверить, работает ли он так, как я ожидал.

Как видно из вышеизложенного, метод Execute вызывает базовый метод Redirect, поэтому я ожидаю, что будет вызван метод Redirect.

Я использую репозиторий макетов Rhino для создания частичного макета Class1. Созданный макет содержит метод Execute, что замечательно, но не содержит ссылки на метод Redirect, который находится в Class1. Я хочу иметь возможность установить ожидание в фиктивном репозитории, что вызывается метод Redirect.

Какие-нибудь советы или подсказки относительно того, как я мог бы создать тест с имитацией носорога, чтобы достичь того, что я обрисовал в общих чертах?


person amateur    schedule 10.12.2011    source источник


Ответы (2)


Если вам нужно смоделировать этот метод, вполне вероятно, что его поведение настолько сложно, что вы не сможете проверить его напрямую.

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

Например, если метод execute сохранял сущность в базе данных, я бы создал репозиторий, внедрил зависимости через конструктор, а затем попросил бы репозиторий сохранить мою сущность. Затем можно смоделировать весь сотрудничающий класс, используя стандартные методы.

На данный момент кажется, что ваш класс несет ответственность за слишком многое, поэтому у вас возникают проблемы. Моки работают очень эффективно, когда они используются для выражения сотрудничества, что позволяет нам создавать классы с единственной ответственностью, что позволяет нам создавать хорошо спроектированный, поддерживаемый код. Я рекомендую книгу Стива Фримена и Ната Прайса по этой теме.

person Lunivore    schedule 11.12.2011

Вам нужно будет объявить метод базового класса Redirect() как virtual, чтобы Rhino Mocks мог имитировать его. Для меня сработало следующее:

public abstract class BaseClass
{
    public abstract void Execute();

    public virtual void Redirect()
    {
        // redirect code here
    }
}

public class Class1 : BaseClass
{
    public override void Execute()
    {
        // do some processing

        this.Redirect();
    }
}

..
var class1Mock = Rhino.Mocks.MockRepository.GeneratePartialMock<Class1>();

class1Mock.Expect(x => x.Redirect());
class1Mock.Execute();
class1Mock.VerifyAllExpectations();
person BrokenGlass    schedule 10.12.2011
comment
Большое спасибо за это, очень помогли. Был ли метод Redirect защищен в BaseClass, можно ли по-прежнему издеваться над ним, добавив к нему virtual? Или это работает только для общедоступных методов. - person amateur; 12.12.2011