PowerMock + Robolectric +匕首2 [英] PowerMock + Robolectric + Dagger2

查看:163
本文介绍了PowerMock + Robolectric +匕首2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我测试包含以下内容的自定义视图类:


I test custom view class which contain:


  1. android ui元素

  2. 一些逻辑

  3. 静态方法调用

  4. dagger2依赖项

  1. android ui elements
  2. some logic
  3. static methods callings
  4. dagger2 dependencies

所以我使用下一个工具进行测试

So i use next tools for testing


  1. Robolectric用于模拟UI元素

  2. 用于逻辑测试的单元测试

  3. 用于静态方法模拟的PowerMock

Robolectric + PowerMock集成问题已知,解决方案已知- https://github.com/robolectric/robolectric/ wiki / Using-PowerMock

但是使用此解决方案,dagger2依赖项失败。


注意编码。

我的自定义视图:

Robolectric + PowerMock integration problem is known and solution is known - https://github.com/robolectric/robolectric/wiki/Using-PowerMock
But with this solution dagger2 dependencies fail.

Attention to code.
My custom view:

public class ProgressTextView extends TextView {

    private String defaultText;
    private int fileSize;
    private String fileSizeString;
    private FileDownloaderI fileDownloader;

    @Inject
    FileDownloaderManager fileDownloaderManager;

    Subscription downloadProgressChannelSubscription;
    Subscription downloadCancelChannelSubscription;

    public ProgressTextView(Context context) {
        super(context);
        provideDependency();
    }

    public ProgressTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        provideDependency();
    }

    public ProgressTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        provideDependency();
    }

    private void provideDependency() {
        ApplicationSIP.get().applicationComponent().inject(this);
    }

}

ProgressTextViewTest:

ProgressTextViewTest:


@RunWith(RobolectricUnitTestRunner.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Formatter.class)
public class ProgressTextViewTest {

    Activity activity;
    @Mock
    FileDownloaderManager fileDownloaderManager;

        @Rule
        public PowerMockRule rule = new PowerMockRule();

        @Before
        public void beforeTest() {
            // PowerMockito
            PowerMockito.mockStatic(Formatter.class);
            when(Formatter.formatFileSize(anyObject(), anyInt())).thenReturn("");
            // Mockito
            MockitoAnnotations.initMocks(this);
            // Robolectic
            activity = Robolectric.setupActivity(Activity.class);
        }

        @Test
        public void init_FileDownloaded() {
            ProgressTextView progressTextView = new ProgressTextView(activity);
        }

}

In ProgressTextViewTest错误:

In ProgressTextViewTest error:

java.lang.NullPointerException
at com.tg.osip.ApplicationSIP.get(ApplicationSIP.java:64)
at com.tg.osip.ui.general.views.ProgressTextView.provideDependency(ProgressTextView.java:56)
at com.tg.osip.ui.general.views.ProgressTextView.<init>(ProgressTextView.java:42)
at com.tg.osip.ui.general.views.ProgressTextViewTest.init_FileDownloaded(ProgressTextViewTest.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
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.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:638)
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 org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
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:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

有一个麻烦了。其他具有Robolectric和dagger2依赖项的测试无法正常工作。


ProgressDownloadViewTest_AudioType:

And there is one trouble yet. Other tests with Robolectric and dagger2 dependencies are not working.

ProgressDownloadViewTest_AudioType:


@RunWith(RobolectricUnitTestRunner.class)
public class ProgressDownloadViewTest_AudioType {

    Activity activity;
    @Mock
    FileDownloaderManager fileDownloaderManager;
    @Mock
    MediaManager mediaManager;

        @Before
        public void setup() {
            // Mockito
            MockitoAnnotations.initMocks(this);
            // Robolectic
            activity = Robolectric.setupActivity(Activity.class);
        }

        @Test
        public void setDownloadingState_emptyFileDownloaderI() {
            ProgressDownloadView progressDownloadView = new ProgressDownloadView(activity, ProgressDownloadView.Type.AUDIO);
            ...
        }

}

例外:


    ClassCastException occurred while creating the mockito proxy :
  class to mock : 'com.tg.osip.tdclient.update_managers.FileDownloaderManager', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@403f0a22'
  created class : 'com.tg.osip.tdclient.update_managers.FileDownloaderManager$$EnhancerByMockitoWithCGLIB$$a751cd05', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@403f0a22'
  proxy instance class : 'com.tg.osip.tdclient.update_managers.FileDownloaderManager$$EnhancerByMockitoWithCGLIB$$a751cd05', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader@10bd9df0'
  instance creation by : ObjenesisInstantiator

You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
    at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
    at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
    at com.tg.osip.ui.general.views.progress_download.ProgressDownloadViewTest_AudioType.setup(ProgressDownloadViewTest_AudioType.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    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.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
    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:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassCastException: Cannot cast com.tg.osip.tdclient.update_managers.FileDownloaderManager$$EnhancerByMockitoWithCGLIB$$a751cd05 to com.tg.osip.tdclient.update_managers.FileDownloaderManager
    at java.lang.Class.cast(Class.java:3369)
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:59)
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
    at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
    at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
    at org.mockito.Mockito.mock(Mockito.java:1284)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
    ... 36 more

更新

解决 PowerMock + Robolectric + Dagger2。第一部分

推荐答案

Activity activity;
@Mock
FileDownloaderManager fileDownloaderManager;

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Before
    public void beforeTest() {

        // You intialise activity here
        activity = Robolectric.setupActivity(Activity.class);
    }

    @Test
    public void init_FileDownloaded() {

        // and use it here, the initialisation is out of scope for this
        ProgressTextView progressTextView = new ProgressTextView(activity);
    }

您需要更改程序逻辑以允许如下所示:

You need to change your program logic to allow for something like this:

Activity activity;
@Mock
FileDownloaderManager fileDownloaderManager;

    activity = Robolectric.setupActivity(Activity.class);

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Before
    public void beforeTest() {

    }

    @Test
    public void init_FileDownloaded() {

        ProgressTextView progressTextView = new ProgressTextView(activity);
    }

 ApplicationSIP.get().applicationComponent().inject(this);

我不确定您指的是 this

我看不到您在类中初始化 FileDownloaderManager 的位置,但看来您正在尝试将自定义管理器用作内置的android管理器。

I cannot see where you are initialsing FileDownloaderManager in you classes, but it seems you are attempting to use the custom manager as the inbuilt android manager.

Caused by: java.lang.ClassCastException: Cannot cast com.tg.osip.tdclient.update_managers.FileDownloaderManager$$EnhancerByMockitoWithCGLIB$$a751cd05 to com.tg.osip.tdclient.update_managers.FileDownloaderManager
at java.lang.Class.cast(Class.java:3369)

我希望这有助于使您更加清晰。

I hope this helps to get you a little clearer.

这篇关于PowerMock + Robolectric +匕首2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆