Android Instrumentation在使用AndroidJunitRunner和AndroidJUnit4时测试java.lang.UnsatisfiedLinkError [英] Android Instrumentation test java.lang.UnsatisfiedLinkError on using AndroidJunitRunner and AndroidJUnit4

查看:106
本文介绍了Android Instrumentation在使用AndroidJunitRunner和AndroidJUnit4时测试java.lang.UnsatisfiedLinkError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在单元测试中使用了robolectric.最近,在我们的项目中,我们正在从zendesk添加新的依赖项.

I am using robolectric in our unit tests. Recently in our project, we are adding a new dependency from zendesk.

repositories {

    maven {
        url 'https://zendesk.artifactoryonline.com/zendesk/repo'
    }
}

compile group: 'com.zendesk', name: 'sdk', version: '1.3.0.1'

现在,我们甚至没有从该库中引用任何类,仅通过添加此依赖项,我们在robolectric单元测试中就获得了异常.我以为问题出在我们的项目中,但是它也在一个示例性的Robolectric测试项目中发生.

Now we have not even referenced any class from this library and we are getting exceptions in our robolectric unit tests just by adding this dependency. I thought the problem is in our project, but its also occurring on a sample robolectric test project.

java.lang.VerifyError: Expecting a stackmap frame at branch target 31
Exception Details:
  Location:
    com/zendesk/sdk/power/BatteryStateBroadcastReceiver.onReceive(Landroid/content/Context;Landroid/content/Intent;)
V @13: ifnonnull
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: b200 1212 0703 bd00 0fb8 0015 2cc7 0012
    0x0000010: b200 1212 0303 bd00 0fb8 0017 a700 66b2
    0x0000020: 0012 bb00 1159 b700 1c12 04b6 001d 2cb6
    0x0000030: 0014 b600 1db6 001e 03bd 000f b800 1512
    0x0000040: 062c b600 14b6 001b 9900 1ab2 0012 1202
    0x0000050: 03bd 000f b800 162b b800 1804 b600 19a7
    0x0000060: 0023 1205 2cb6 0014 b600 1b99 0017 b200
    0x0000070: 1212 0103 bd00 0fb8 0016 2bb8 0018 03b6
    0x0000080: 0019 b200 1212 0803 bd00 0fb8 0015 b1  

at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.robolectric.internal.Shadow.newInstanceOf(Shadow.java:15)
at org.robolectric.shadows.ShadowApplication.registerBroadcastReceivers(ShadowApplication.java:148)
at org.robolectric.shadows.ShadowApplication.bind(ShadowApplication.java:137)
at org.robolectric.shadows.CoreShadowsAdapter.bind(CoreShadowsAdapter.java:99)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:121)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:421)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:234)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:185)
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:149)
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)

推荐答案

找到了解决方案.我们在测试用例中没有使用zendesk代码.通过gradle构建,来自添加的依赖项(zendesk)的广播接收器已添加到AndroidManifest.xml中. RobolectricTestRunner类将清单解析为其内部ApplicationManifest对象,然后通过ShadowApplication类设置应用程序状态. ShadowApplication类从应用程序清单中注册广播接收者.这是我收到上述错误的地方.

Found the fix for this. We were not using zendesk code in our test cases. The broadcast receivers from the added dependency(zendesk) were getting added to AndroidManifest.xml through the gradle build. The RobolectricTestRunner class parses the manifest into its internal ApplicationManifest object and then sets up application state through ShadowApplication class. The ShadowApplication class registers broadcast receivers from the application manifest. This is where I was getting the above error.

修复: 我们有一个自定义测试运行程序,它扩展了RobolectricGradleTestRunner. 这样,我重写了getAppManifest方法并删除了不需要的广播接收器.我知道这是一种解决方法,但没有其他选择.不想创建另一个清单并创建重复项.这是代码段.

Fix: We have a custom test runner that extends RobolectricGradleTestRunner. In that I have overriden the getAppManifest method and removed the broadcast receivers not required. I know its a kind of workaround but there was no other alternative. Didn't want to create another manifest and create duplication. Here's the code snippet.

@Override
protected AndroidManifest getAppManifest(org.robolectric.annotation.Config config) {
    AndroidManifest manifest = super.getAppManifest(config);
    List<BroadcastReceiverData> broadcastReceivers = manifest.getBroadcastReceivers();
    List<BroadcastReceiverData> removeList = new ArrayList<>();
    for(BroadcastReceiverData receiverData : broadcastReceivers) {
        if(isDeletePackage(receiverData.getClassName())) {
            removeList.add(receiverData);
        }
    }
    broadcastReceivers.removeAll(removeList);
    return  manifest;
}

private boolean isDeletePackage(String className) {
    for(String s : DELETE_BROADCAST_PACKAGE) {
        if(className.startsWith(s)) {
            return true;
        }
    }
    return false;
}

DELETE_BROADCAST_PACKAGE只是一个字符串哈希集.包含程序包层次结构名称

The DELETE_BROADCAST_PACKAGE is simply a String hashset. Containing the package hierarchy name

这篇关于Android Instrumentation在使用AndroidJunitRunner和AndroidJUnit4时测试java.lang.UnsatisfiedLinkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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