PowerMockito: NotamockException на макет

Немного сложной настройки. Robolectric, конфигурация на основе правил PowerMockito.

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) // Using "PrepareOnlyThis" prevents powermock from trying to instrument the whole hierarchy, // part of which we've ignored (android.os.* in this case) @PrepareOnlyThisForTest({ServiceCallbackBase.class}) // this class extends Handler, // so we need PrepareOnlyThis. It also has some final methods we need to verify() public class ServiceBaseTests { private class Foo { // nothing } @Rule public PowerMockRule rule = new PowerMockRule(); private ServiceCallbackBase<Object, Foo> setupCallback( boolean hasValidContext, boolean allContextsCanceled ) { ServiceCallbackBase<Object, Foo> callback = PowerMockito.mock( ServiceCallbackBase.class ); // EDIT: I have converted these to PowerMockito.doReturn()s to no avail. PowerMockito.when( callback.hasValidContext() ).thenReturn( hasValidContext ); PowerMockito.when( callback.allContextsAreCanceled( any( Message.class ) ) ).thenReturn( allContextsCanceled ); PowerMockito.doNothing().when( callback ).preSendMessage( any( Message.class ) ); return callback; } 

Должно быть довольно рутиной. Но всякий раз, когда я пытаюсь вызвать verify на одном из этих экземпляров «обратного вызова», например:

  private void test_notifyCallback( boolean isFromCache ) { ServiceCallbackBase<Object, Foo> callback = setupCallback( true, false ); uut.addHandler( TestEnum.FOO, callback ); uut.addHandler( TestEnum.BAR, PowerMockito.mock( ServiceCallbackBase.class ) ); uut.addHandler( TestEnum.BAZ, PowerMockito.mock( ServiceCallbackBase.class ) ); Response<Foo> foo = new Response<>( new Foo(), new ResponseStatus( 0, "Error" ) ); uut.handleCallBack( TestEnum.FOO, foo, isFromCache ); ArgumentCaptor<Message> captor = ArgumentCaptor.forClass( Message.class ); // this line throws the error. verify( callback ).preSendMessage( captor.capture() ); assertThat( captor.getValue().what ).isEqualTo( TestEnum.FOO.ordinal() ); assertThat( captor.getValue().obj ).isEqualTo( foo ); assertThat( captor.getValue().arg1 ).isEqualTo( isFromCache ? 1 : 0 ); } 

Я получаю ошибку:

 org.mockito.exceptions.misusing.NotAMockException: Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$9acf906b and is not a mock! Make sure you place the parenthesis correctly! See the examples of correct verifications: verify(mock).someMethod(); verify(mock, times(10)).someMethod(); verify(mock, atLeastOnce()).someMethod(); 

Он явно и явно «улучшен» mockito, а PowerMock не использует метод Mockito.verify() вместо Mockito.verify() … что дает?

EDIT : это в некотором роде больше и в некотором смысле менее запутанно.

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

 @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class ServiceCallbackBaseTests { @Test public void test_nothing(){ } private ServiceCallbackBase<Object, String> uutSpy; @Before public void setup(){ uutSpy = mock( ServiceCallbackBase.class ); } } 

Solutions Collecting From Web of "PowerMockito: NotamockException на макет"

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

 @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) @PrepareOnlyThisForTest({ServiceCallbackBase.class, Dummy.class}) public class MainActivityTest { @Rule public PowerMockRule rule = new PowerMockRule(); @Test public void test1() throws Exception { try { //This Mockito.withSettings() thing is important to make the test fail! ServiceCallbackBase callback = PowerMockito.mock( ServiceCallbackBase.class, Mockito.withSettings()); callback.dispatchMessage(null); Mockito.verify(callback).dispatchMessage(null); } catch (Exception e){ e.printStackTrace(); Assert.fail(); } } } 

(Обратите внимание на Mockito.withSettings (), я не знаю, почему, но это заставляет тест сбой)

Печать:

 org.mockito.exceptions.misusing.NotAMockException: Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$62776c54 and is not a mock! Make sure you place the parenthesis correctly! ...... 

Ну, это абсолютно выглядит как проблема с загрузкой, mockito сравнивает ServiceCallbackBase $$ EnhancerByMockitoWithCGLIB $$ и т. Д., Загруженные Powermock с тем же загруженным Robolectric (явно возвращающим false в этом сравнении)

Затем мне удалось сделать тестовую работу простым добавлением "org.powermock.*" К строке @PowerMockIgnore... это:

 @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "org.powermock.*"}) 

Это простое изменение заставило мой тест работать, и я действительно надеюсь, что вы тоже заработаете.

Я столкнулся с этой проблемой. На самом деле проблема в проекте PowerMock: https://github.com/jayway/powermock/issues/593

Но никаких комментариев ни от одного из разработчиков powermock.