Подтвердить что ты не робот

Ноки и носки Rhino Mocks хороши только для интерфейсов?

Правильно ли, что ноки и макеты Rhino Mocks хороши только для интерфейсов, а не для конкретных классов? Я потратил много времени, пытаясь заставить этот кусок кода работать. Я не ожидал, что stubbed pubSubClient всегда будет вызывать метод Send из класса. Этот метод имеет некоторые зависимости и исключает исключение.

[Test]
public void Test01()
{
    PubSubMessage psm = new PubSubMessage(); 
    var pubSubClient = MockRepository.GenerateStub<PubSubClient>();
    pubSubClient.Stub(x => x.Send(psm)).IgnoreArguments().Return(null);
    // actual PubSubClient Send method throws exception
    // the rest of the test is skipped...
}

Однако, когда я извлек интерфейс и запустил тот же тест с помощью IPubSubClient, он работает как ожидалось.

Означает ли это, что мне нужно извлечь интерфейс для каждого класса, который я хочу издеваться/заглушить с Rhino? Или я чего-то не хватает, технически или концептуально?

ОБНОВЛЕНИЕ: ОК. Кажется, я выяснил, в какой части я отсутствовал: Rhino Mocks не может перехватывать вызовы не виртуальным методам. Итак, я предполагаю, что у меня есть либо используемые интерфейсы, либо каждый метод для конкретного класса виртуальный. Пожалуйста, поправьте меня, если есть другой вариант.

4b9b3361

Ответ 1

Ответ Брайана на частичные издевательства неверен. Это не то, что для частичных макетов.

Ответ Джона Эриксона в основном правильный: Rhino Mocks и Moq не могут перехватывать не виртуальные вызовы, а также не могут перехватывать статические методы или свойства. Это означает, что вы не можете подделать следующее:

DateTime.Now; // static property, can't fake static property
someClass.SomeNonVirtualMethod(); // can't fake non-virtual method
sealedClass.Foo(); // can't fake anything on sealed classes
Utilities.SomeStaticMethod(); // can't fake static methods
someList.Any(); // can't fake extension methods like Linq .Any()

TypeMock может подделать их, как сказал Джон.

Следует отметить, что существует еще одна из насмешливая структура, которая может перехватывать все вызовы: Microsoft Moles framework. Он работает так же, как и TypeMock, он использует API-интерфейс профилирования .NET для перехвата вызовов.

Молы свободны (на данный момент). Это также бета-версия. Moles работает только с Microsoft Pex tools. И его API явно уступает уточненному, элегантному API TypeMock.

Ответ 2

Вы должны сделать методы виртуальными. Rhino mocks (и большинство других рамок изоляции) использует прокси-классы для создания заглушек /mocks.

Если вы используете TypeMock Isolator, вы можете издеваться над чем-либо, потому что эта среда изоляции использует API-интерфейс .NET Profiler для создания своих "stubs/mocks"

Ответ 3

Это существенно правильное и, как правило, хорошая практика. Однако он действительно полезен только для определенного типа кодирования.

Не думайте об объектах как о вещах, которые может манипулировать какой-то "высшей силой". Вместо этого подумайте о них как о автономных "людях", которые могут отправлять сообщения друг другу. Интерфейс представляет сообщения, отправленные одним объектом.

Затем вы используете mocks для проверки правильности отправки сообщений, а не для подделки реализаций зависимостей.

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

Ответ 5

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