2013-05-06 12 views
5

У меня есть следующий класс:PowerMockito: как издеваться над методами, вызываемыми конструктором?

public class Foo { 

    public Foo() { 
    initField1(); 
    initField2(); 
    initField3(); 
    } 

} 

мне нужно изменить поведение (высмеивать) initField1() и initField3() для них делать ничего не делать или что-то еще, что они на самом деле. Я заинтересован в выполнении фактического кода initField2().

Я хочу написать следующий тест:

Foo foo = new Foo(); 
assertTrue(foo.myGet()); 

myGet() возвращает атрибут Foo, который был вычисленной initField2().

Методы initField(), конечно, являются частными.

Как я могу это сделать?

Спасибо за вашу помощь и наилучшие пожелания.

ответ

-1

Я думаю, что что-то не так в том, что вы хотите сделать.

Насколько я понимаю, издевательская структура, такая как Mockito или PowerMock, предназначена для взаимодействия между тестируемым объектом и его зависимостями.

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

В вашем случае, вы хотите проверить что-то, что никогда не произойдет, так как initField2() никогда не будет вызываться без звонков initField1() и initField3()

Если причина не хотите звонить initField1() и initField3 потому, что эти методы взаимодействуют с другими объектами или файловой системой или БД, тогда вам следует скорее вводить зависимости через аргумент конструктора или аннотированные сеттеры и просто вводить макеты для своих тестов. И чтобы создать экземпляр объекта с правильно настроенными зависимостями, используйте шаблон фабрики, шаблон построителя или даже лучше, используйте инфраструктуру инъекции зависимостей, такую ​​как шаблон Spring или Google Guice.

Если причина вы d'ОНТ хотите позвонить initField1() и initField3 потому, что они имеют дело с различными бизнес-логики в вашем объекте, то это пахнет (как в http://martinfowler.com/books/refactoring.html), как вы нарушаете единый принцип ответственности, и вы должны рефакторинг.

+0

Это устаревший код. Я предпочитаю не изменять тестируемый класс, называя новый конструктор, принимающий аргументы, например. Я хочу, чтобы выполнялся только 'initField2()', потому что он отвечает за настройку поля, которое я хочу проверить. Мне не интересно тестировать остальную логику конструктора. –

+0

Mockito предназначен для моделирования взаимодействия, PowerMock предназначен для издевательства над частичной внутренней обработкой класса для устаревшего кода, поэтому этот ответ просто неверен. – eis

5

Принимая во внимание все может случиться в унаследованного кода :) вы можете использовать PowerMock для подавления методы, как описано в http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior

import static org.powermock.api.support.membermodification.MemberMatcher.methods; 
import static org.powermock.api.support.membermodification.MemberModifier.suppress; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Foo.class) 
public class FooTest { 

    @Test 
    public void testSuppressMethod() throws Exception { 
     suppress(methods(Foo.class, "initField1", "initField3")); 
     Foo foo = new Foo(); 
    } 
} 

Тем не менее, вы должны переделан класс после того, как вы получили достаточный охват испытаний для него ,

+0

Большое спасибо. Он работает сейчас! Еще один вопрос, как я могу проверить, вызван ли 'initField2()'? Я думал о том, чтобы шпионить за моим новым Foo, но на самом деле нет никакого взаимодействия с ним, поэтому 'verifyPrivate (foo) .invoke (initField2)' не помогает. –

+0

@JulienCollah вы проверите это косвенно, проверив, что 'foo.myGet()' возвращает правильное значение. –

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