2017-02-13 36 views
3

У меня есть статический метод, который проверяет статус Интернета, использующего контекст. Поэтому, чтобы издеваться над этим, мне нужно использовать PowerMock. Я использую robolectric, чтобы ускорить мой тест, поскольку единственное, что мне нужно, - это насмехаться. Но я не могу настроить PowerMock (1.6.6) и Robolectric (3.2.2) для совместной работы. Это, как я аннотирование моего класса:Как комбинировать PowerMock и Robolectric

@RunWith(RobolectricTestRunner.class) 
@org.robolectric.annotation.Config(constants = BuildConfig.class, sdk = 21) 
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) 
@PrepareForTest({Utils.class}) 

и эта строка в методе установки:

PowerMockito.mockStatic(Utils.class); 

Но я получаю это исключение:

org.powermock.api.mockito.ClassNotPreparedException: 
The class com.zeyad.usecases.data.utils.Utils not prepared for test. 
To prepare this class, add class to the '@PrepareForTest' annotation. 
In case if you don't use this annotation, add the annotation on class or method level. 

at org.powermock.api.mockito.expectation.reporter.MockitoPowerMockReporter.classNotPrepared(MockitoPowerMockReporter.java:32) 
at org.powermock.api.mockito.internal.mockcreation.MockTypeValidatorFactory$DefaultMockTypeValidator.validate(MockTypeValidatorFactory.java:38) 
at org.powermock.api.mockito.internal.mockcreation.AbstractMockCreator.validateType(AbstractMockCreator.java:10) 
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:56) 
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46) 
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:71) 
at com.zeyad.usecases.data.repository.stores.DataStoreFactoryJUnitTest.setUp(DataStoreFactoryJUnitTest.java:39) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:339) 
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:259) 
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:41) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:199) 

Моих зависимости build.gradle файлов:

testCompile "junit:junit:$junit" 
testCompile "org.hamcrest:hamcrest-library:$hamcrest" 
testCompile "com.android.support:support-annotations:$supportLibraryVersion" 
testCompile "org.mockito:mockito-core:1.10.19" 
testCompile "org.robolectric:robolectric:$robolectric" 
testCompile "org.robolectric:shadows-support-v4:$robolectric" 
testCompile "org.powermock:powermock-module-junit4:$powerMock" 
testCompile "org.powermock:powermock-module-junit4-rule:$powerMock" 
testCompile "org.powermock:powermock-api-mockito:$powerMock" 
testCompile "org.powermock:powermock-classloading-xstream:$powerMock" 

ответ

2

Иногда ответ i чтобы просто отступить и заглянуть в вашу «потребность» в использовании PowerMock.

Итак, у вас есть метод статический метод, который нуждается в PowerMock для проверки?

Затем просто не делайте код статический. И тогда ваша потребность использовать PowerMock просто исчезает.

Просто замените его комбинацией интерфейса, класса impl (и, возможно, enum singleton, если вам нужна «точно» одна его реализация).

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

или другими словами: узнайте, как написать testable код и сделать это; вместо создания жесткого кода, который требует, чтобы большой молот PowerMock стал тестируемым. Посмотрите на эти videos, чтобы узнать, как это сделать.

Я не эксперт для RoboElectric, но я предположим, что: проблема может быть в том, что для обеих фреймворков нужен свой конкретный @Runner. Таким образом: возможно, это помогает here; поскольку в ответах предлагается использовать PowerMock без с использованием PowerMockRunner.

+1

Ну да, вы правы. Но было бы неплохо узнать, как сделать robolectric и PowerMock работать вместе? –

+0

Если бы я знал; Я бы это записал ... но хорошо, у меня была идея и обновил мой ответ. Может быть, это помогает. – GhostCat