2012-04-25 3 views
0

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

Пример кода:

public class Foo 
{ 
    public Foo() 
    { 
     Initialize(); 
    } 

    private void Initialize() 
    { 
     //some code 
    } 
} 

[TestFixture] 
public class Test 
{ 
    [Test] 
    public void Test_Foo() 
    { 
     Foo foo = MockRepository.GenerateMock<Foo>(); 

     //some test 
    } 
} 

Примечания:

  1. Я не хочу, чтобы добавить интерфейс, как Foo : IFoo.
  2. Я не хочу добавлять второй конструктор.
+2

Вы не можете этого сделать. Вам нужно либо добавить второй конструктор, либо делегировать '.Initialize' на зависимость и впрыск. Что именно вы испытываете? Тестирование насмешливого объекта не имеет смысла, надеюсь, вы это знаете. –

+0

Вы можете создать экземпляр Foo без вызова конструктора с помощью 'FormatterServices.GetUninitializedObject (...)'. Подробнее см. Здесь: http://stackoverflow.com/questions/178645/how-does-wcf-deserialization-instantiate-objects-without-calling-a-constructor – JYL

ответ

0

В общем, вы можете создавать только макеты интерфейсов или абстрактных классов.

Что вы собираетесь тестировать? Если это класс Foo, то создание макета из него совершенно неверно.

Обычно вы создаете mocks тех зависимых объектов вашего тестируемого класса, которые трудно настроить или занять много времени. Наиболее распространенным примером такой зависимости является репозиторий или веб-сервис.

+0

Вы пишете. Это простой пример, но этот пример показывает мою проблему. Возьмем Foo как абстрактный класс. – Rougher

+0

В любом случае, если вы проверите Foo, то создайте макет, если это неправильный подход. –

+0

@IvanGerken: * «вы можете создавать только mocks интерфейсов или абстрактных классов» * - это не так; Rhino также может издеваться над нормальным классом, в этом нет ничего особенного. Если класс предоставляет виртуальные методы, то эти методы можно издеваться так же, как если бы это был интерфейс. –

0

Как ABT добавление логического флага

Логический флаг = ложь;

[Test]

public void Test_Foo() 
{ 
    if(flag == true) 
    { 
     Foo foo = MockRepository.GenerateMock<Foo>(); 

    } 
    //some test 
} 
+0

Я не хочу избегать вызова MockRepository.GenerateMock () ;. – Rougher

1

Когда вы насмешливый класс, есть прокси создан (Rhino использует Castle.DynamicProxy.DefaultProxyBuilder), который наследует от вашего класса. И наследование работает точно так же, как в любом месте C#. Когда вы создаете экземпляр производного типа, вызываются все конструкторы базовых типов (до объекта).

Итак, когда создается экземпляр прокси (через Activator.CreateInstance (typeof (proxy))), будет вызван конструктор Foo. Вы не можете этого избежать. Вы можете использовать интерфейс mocking или предоставить некоторый параметр конструктору, который отключит инициализацию.

BTW, издевающийся над абстрактными или конкретными классами, убивает все преимущества mocks - ваши тесты становятся зависимыми от что-то, которое не издевается (конструкторы, не виртуальные методы и реализации по умолчанию). И ваш SUT (тестируемая система) больше не тестируется в изоляции. Сломанный тест может быть результатом некоторых изменений внутри абстрактного или конкретного класса.

Смежные вопросы