Я думаю, что это возможно с PowerMock, только если метод на дочернем объекте отличается от метода на суперклассе (то есть, вы не можете высмеивать родительский метод, если дочерний метод переопределяет этот метод). Для более подробной информации, вы можете посмотреть соответствующий отчет об ошибке .
Для PowerMock проверьте страницу Подавление нежелательного поведения , чтобы увидеть, будет ли этого достаточно для ваших нужд.
После долгих размышлений я использовал JMockit для этих сложных случаев. Прежде чем перейти к JMockit, я попытался заглушить все места, где исключения были выброшены с использованием подавления. В конце концов, мне нужно было переопределить некоторые методы, а не просто подавить их, поэтому я отказался от них.
Пример использования для случая Android:
Сначала вы макетируете свой суперкласс, используя аннотацию @MockClass
:
@MockClass(realClass = Activity.class, instantiation = PerMockedInstance)
public class FakeActivity {
public Bundle mSavedInstanceState;
@Mock
public void $init() {}
@Mock
public void onCreate(Bundle savedInstanceState) {
mSavedInstanceState = savedInstanceState;
}
}
При активации этот класс заменит конструктор по умолчанию Activity
на $init()
и заменит метод onCreate
на приведенный выше. С android тестируемый модуль получен из Activity (в моем примере кода это HelloTestActivity
). Тестовый класс выглядит так:
public class HelloTestActivityTest3 extends AndroidTest {
@Tested
HelloTestActivity activity;
FakeActivity fakeActivity = new FakeActivity();
@Before
public void setupMocks()
{
Mockit.setUpMock(fakeActivity);
}
@Test
public void onCreate_bundle(@Mocked Bundle savedInstanceState)
{
// Try to access out-of-band information from the fake
activity.onCreate(savedInstanceState);
assertSame(savedInstanceState, fakeActivity.mSavedInstanceState);
}
}
Звонок Mockit.setupMock(fakeActivity)
заменяет суперкласс моим экземпляром подделки. При таком использовании вы также можете получить доступ к внутреннему состоянию вашего поддельного класса. Если вам не нужно переопределять какие-либо методы с пользовательскими функциями, вы можете использовать другие методы, доступные в Mockit
class.
Как указал rogerio в комментариях ниже, насмешка над классом Activity
- это минимум. Следующий код демонстрирует это.
public class HelloTestActivityTest4 {
@Tested
HelloTestActivity activity;
@Mocked
Activity base;
@Test
public void testOnCreate() throws Exception {
// Just make sure "Stub!" exception is not thrown.
activity.onCreate(null);
}
}
Объявление @Mocked Activity base;
вызывает все методы (за исключением статических инициализаторов) класса Activity
и его суперклассов для проверки в тестах, определенных в HelloActivityTest4
.