2012-05-02 3 views
1

Я хотел бы знать, могу ли я высмеять вызов конструктора суперкласса и его вызовы super().Mock конструктор суперкласса

Например, у меня есть следующие классы

class A 
{ 
    A(..) 
    { 
     super(..) 
    } 
} 

class B extends A 
{ 
    B(C c) 
    { 
     super(c) 
    } 
} 

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

Спасибо!

+7

Что * точно * затрудняет тестирование B? Тот факт, что он называет конструкторы суперкласса, не является * неотъемлемо * проблематичным. Вы должны пытаться высмеять * зависимости *, а не поведение самого объекта. –

+0

Я обсуждаю [подавление ctors с помощью PowerMock с EasyMock в этом сообщении блога] (http://buckybits.blogspot.com/2011/11/testing-singletons-and-static-classes.html), у меня нет Mockito версия. Однако неясно, хотите ли вы уничтожить ctor или заменить его. –

+1

@ Jon Skeet. да, я понимаю это, но для того, чтобы добиться этого, он сложный и запускает несколько потоков в фоновом режиме, вызывая множество внешних зависимостей, которые не нужны для моего модульного теста. – Rishi

ответ

1

Вы можете использовать библиотеку PowerMock. Это действительно спасатель, когда вам нужно выполнить такие вещи, как ваша. https://github.com/jayway/powermock/wiki/SuppressUnwantedBehavior

+0

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

0

Короткий ответ на ваш вопрос: «Не совсем». Вы не можете «макет» конструктора, не говоря уже о супер. Также издевательский super.anyMethod трудно или невозможно с насмешливыми фреймворками, с которыми я знаком. Powermock делает позволяет подавлять суперконструкторы и проблемные методы, что не совсем то же самое, что насмехаться над ними, но может помочь.

Когда B расширяет A, он, конечно, полностью связан с A. Это не проблема как таковой, но это может быть и похоже, что он находится здесь. Вместо того, чтобы B растянуть A, попробуйте B включить A вместо (и, возможно, реализовать тот же интерфейс, если необходимо). Затем вы можете ввести макет A и делегировать все вызовы, которые вы хотите. Это было бы намного проще для модульного теста, нет?

Это одно из преимуществ разработки, основанной на испытаниях, которую вы обнаружите в своем дизайне во время тестирования.

+0

См. Выше re: PowerMock. Независимо от того, является ли это хорошей идеей или нет, возможно замену конструктора во время выполнения. –

1

Отказывание конструктора - очень плохая идея. Это происходит по обходному поведению, которое будет происходить в производстве. Вот почему выполнение работы в конструкторе, например, запуск потоков и вызов внешних зависимостей, - это design flaw.

Можете ли вы честно сказать, что работа, выполненная в конструкторе, не влияет на поведение, которое вы пытаетесь протестировать? Если ответ отрицательный, вы рискуете написать тест, который пройдет в тестовой среде, но не сработает. Если ответ «да», это простой случай для перемещения «работы» вне конструктора. Другой альтернативой является перемещение поведения, которое вы пытаетесь протестировать в другом классе (возможно, оно собственное).

Это еще более верно, если вы используете фреймворк DI, такой как Guice (который я предполагаю, потому что вы отметили его таким образом).