2012-06-01 6 views
4

Как обсуждалось в этой ссылке - https://groups.google.com/group/powermock/browse_thread/thread/25ba2b85d9e576f4, я попытался использовать PowerMock с Robolectric, чтобы издеваться над статическим методом. Но это бросает некоторые трудно понятные исключения.Невозможно использовать PowerMock с Robolectric

Ниже мой тестовый класс:

package net.therap.passreset.service; 

import android.content.Context; 
import com.xtremelabs.robolectric.Robolectric; 
import net.therap.passreset.util.ConnectivityStatus; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.rule.PowerMockRule; 
import roboguice.RoboGuice; 
import roboguice.activity.RoboActivity; 
import roboguice.test.RobolectricRoboTestRunner; 

import static org.easymock.EasyMock.expect; 
import static org.powermock.api.easymock.PowerMock.mockStatic; 

/** 
* @author sharafat 
*/ 
@RunWith(RobolectricRoboTestRunner.class) 
@PrepareForTest(ConnectivityStatus.class) 
public class TherapWebServiceClientTest { 
    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 

    private Context context = new RoboActivity(); 
    private TherapWebServiceClient therapWebServiceClient; 

    @Before 
    public void setUp() throws Exception { 
     RoboGuice.setBaseApplicationInjector(Robolectric.application, RoboGuice.DEFAULT_STAGE); 
     therapWebServiceClient = RoboGuice.getInjector(context).getInstance(TherapWebServiceClient.class); 
     mockStatic(ConnectivityStatus.class); 
    } 

    @After 
    public void tearDown() throws Exception { 
     RoboGuice.util.reset(); 
    } 

    @Test 
    public void testLogin_success() { 
     Robolectric.setDefaultHttpResponse(200, ""); 
     expect(ConnectivityStatus.isInternetConnected(context)).andReturn(true); 

     therapWebServiceClient.login("", "", ""); 
    } 
} 

Запуск теста дает следующее исключение:

com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field roboguice.activity.RoboActivity.__shadow__ 
---- Debugging information ---- 
field    : __shadow__ 
class    : roboguice.activity.RoboActivity 
required-type  : roboguice.activity.RoboActivity 
converter-type  : com.thoughtworks.xstream.converters.reflection.ReflectionConverter 
path    : /org.powermock.modules.junit4.rule.PowerMockStatement$1/outer-class/fNext/fNext/fNext/fTarget/context/__shadow__ 
line number   : 16 
class[1]   : net.therap.passreset.service.TherapWebServiceClientTest 
class[2]   : org.junit.internal.runners.statements.InvokeMethod 
class[3]   : org.junit.internal.runners.statements.RunBefores 
class[4]   : org.junit.internal.runners.statements.RunAfters 
class[5]   : org.powermock.modules.junit4.rule.PowerMockStatement 
class[6]   : org.powermock.modules.junit4.rule.PowerMockStatement$1 
version    : null 
------------------------------- 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.determineType(AbstractReflectionConverter.java:453) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:294) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:355) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:306) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:234) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) 
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1052) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1036) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:912) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:903) 
    at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:54) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:89) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) 
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49) 
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:292) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runners.Suite.runChild(Suite.java:128) 
    at org.junit.runners.Suite.runChild(Suite.java:24) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 


Process finished with exit code 255 

Если удалить context поле из класса и заменить его new RoboActivity() в другом месте в коде , то исключается следующее исключение:

java.lang.NullPointerException 
    at roboguice.RoboGuice.setBaseApplicationInjector(RoboGuice.java:116) 
    at net.therap.passreset.service.TherapWebServiceClientTest.setUp(TherapWebServiceClientTest.java:33) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30) 
    at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:52) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:2014) 
    at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:885) 
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:713) 
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) 
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49) 
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:292) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runners.Suite.runChild(Suite.java:128) 
    at org.junit.runners.Suite.runChild(Suite.java:24) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 


Process finished with exit code 255 

Вышеприведенное исключение, по-видимому, указывает на то, что Robolectric не может создать контекст приложения. Любая идея о том, как я могу заставить обе работать вместе?

ответ

2

Обновите свой PowerMock до версии 1.4.9. Я думаю, что я использую 1.5.1, и я не вижу такой же ошибки. i имеют:

@RunWith(RobolectricTestRunner.class) 
@PrepareForTest(MyStaticClass.class) 

и они не конфликтуют.

см: https://github.com/jayway/powermock/wiki/PowerMockAgent

+1

Большое спасибо. Я попробую, когда у меня будет время. И спасибо за ценную ссылку ... :) –

+0

никаких проблем! не забывайте поднимать и принимать ответ, если он помогает/решает проблему! : D –

2

Я нашел способ использовать PowerMock в сочетании с Robolectric.

В дополнение к стандартным банкам PowerMock также требуется правило PowerMock Junit. Описывается here как его захватить. Я использовал версию загрузки xstream, потому что objenesis один очень плохой. Это работает с PowerMock 1.5.5 и Robolectric 2.3, я не могу говорить о более старых версиях. Также учтите, что Java-агент не должен быть включен, потому что по моему опыту он вызывает проблемы.

Так что, если вы используете Maven, эти зависимости должны быть объявлены:

<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-module-junit4</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-module-junit4-rule</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-api-mockito</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.powermock</groupId> 
    <artifactId>powermock-classloading-xstream</artifactId> 
    <version>${powermock.version}</version> 
    <scope>test</scope> 
</dependency> 

Затем вы должны настроить свой тестовый класс, как это:

@RunWith(RobolectricTestRunner.class) 
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" }) 
@PrepareForTest(Static.class) 
public class MyTest { 

    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 

    private MyActivity activity; 

    @Before 
    public void setup() { 
     activity = Robolectric.buildActivity(MyActivity.class).create().get(); 
    } 

    @Test 
    public void test() throws Exception { 
     PowerMockito.mockStatic(Static.class); 
     Mockito.when(Static.getCurrentTime()).thenReturn(1); 

     Assert.assertEquals(1, activity.getId()); 
    } 
} 
+0

Эта настройка позволит использовать функции mockStatic и другие функции Powermock, но ** вы не сможете издеваться над системными классами Android **, поскольку они заменяются классами «org.robolectric. *» Robolectric. – PLNech

+0

@PLNech правда, однако в среде Robolectric вы не хотите издеваться над классами Android, Robolectric делает это для вас. :) Вы все равно можете использовать пользовательские классы теней Robolectric. – WonderCsabo

+0

Хорошая точка, но мне не удалось издеваться над системными классами Android (например, создать mock 'java.net.URL') с помощью Robolectric + PowerMock. Есть ли у вас пример такого использования? – PLNech

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