Тупики Насмешек носорога и насмешки только хороши для интерфейсов?

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

[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, это, кажется, работает как ожидалось.

Это означает, что я должен извлечь интерфейс для каждого класса, который я хочу дразнить/блокировать с Носорогом? Или я пропускаю что-то, технически или концептуально?

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

21
задан Ryan Gates 19 September 2012 в 16:47
поделиться

5 ответов

Ответ Брайана об использовании частичных моков неверен. Не для этого нужны частичные имитации.

Ответ Джона Эриксона в основном правильный: 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, он использует API профилировщика .NET для перехвата вызовов.

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

23
ответ дан 29 November 2019 в 21:28
поделиться

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

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

3
ответ дан 29 November 2019 в 21:28
поделиться

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

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

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

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

2
ответ дан 29 November 2019 в 21:28
поделиться

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

1
ответ дан 29 November 2019 в 21:28
поделиться

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

0
ответ дан 29 November 2019 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: