Заглушки и насмешки Rhino Mocks хороши только для интерфейсов - PullRequest
21 голосов
/ 05 марта 2010

Правильно ли, что заглушки и макеты Rhino Mocks хороши только для интерфейсов, а не для конкретных классов? Я потратил довольно много времени, пытаясь заставить этот кусок кода работать. Я не ожидал, что заглушка 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 не может перехватывать вызовы не виртуальных методов . Итак, я думаю, что я либо использую интерфейсы, либо делаю каждый метод в конкретном классе виртуальным. Пожалуйста, поправьте меня, если есть другой вариант.

Ответы [ 5 ]

23 голосов
/ 06 марта 2010

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

Ответ Джона Эриксона в основном правильный: 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's .Any()

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

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

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

3 голосов
/ 06 марта 2010

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

Если вы используете TypeMock Isolator, вы можете смоделировать что угодно, потому что эта среда изоляции использует .NET Profiler API для создания своих 'заглушек / mocks

2 голосов
/ 06 марта 2010

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

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

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

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

1 голос
/ 05 марта 2010

Частичные макеты позволяют макетировать функциональность конкретного класса.Смотри: http://www.ayende.com/wiki/Rhino+Mocks+Partial+Mocks.ashx

0 голосов
/ 06 марта 2010

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

...