[英]Robolectric tanks on Application objects that load JNI libraries. Can I get a workaround?
我的Android应用程序的Application
对象加载了一个JNI库,而Robolectric似乎并不喜欢这样。 当我去运行我的测试时,Robolectric出来了,我得到了这个堆栈跟踪:
java.lang.UnsatisfiedLinkError:java.lang上的java.lang.ClassLoader.loadLibrary(ClassLoader.java:1758)的java.library.path中没有cperryinc-jni,java.lang.Runtime.loadLibrary0(Runtime.java:823) .system.loadLibrary(System.java:1045)at com.cperryinc.application.MoolaApplication。(MoolaApplication.java:24)at java.lang.Class.forName0(Native Method)at java.lang.Class.forName(Class。 java:169)at com.xtremelabs.robolectric.internal.ClassNameResolver.safeClassForName(ClassNameResolver.java:36)at com.xtremelabs.robolectric.internal.ClassNameResolver.resolve(ClassNameResolver.java:15)at com.xtremelabs.robolectric.ApplicationResolver .newApplicationInstance(ApplicationResolver.java:71)位于com.xtremelabs.robolectric的com.xtremelabs.robolectric.ApplicationResolver.resolveApplication(ApplicationResolver.java:28)com.xtremelabs.robolectric.RobolectricTestRunner.createApplication(RobolectricTestRunner.java:483)。 com.com上的RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:360) tremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:299)位于org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)的com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:277)位于org.junit.runner.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)的.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:193) org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:52)org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)org.junit.runners.ParentRunner.access $ 000(ParentRunner.java) :42)org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:184)org.junit.runners.ParentRunner.run(ParentRunner.java:236)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:182)at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
我不确定我能做些什么。 关于变通方法的任何想法?
感谢Jan Berkel在此处回答: https : //groups.google.com/d/msg/robolectric/beW9XjT8E1A/pJQrRaybN30J
class MyJniClass {
static {
try {
System.loadLibrary("libname");
} catch (UnsatisfiedLinkError e) {
// only ignore exception in non-android env
if ("Dalvik".equals(System.getProperty("java.vm.name"))) throw e;
}
}
}
然后在测试员中:
public class MyTestRunner extends RobolectricTestRunner {
public MyTestRunner(Class testClass) throws InitializationError {
// remove native calls + replace with shadows
addClassOrPackageToInstrument("com.example.jni.MyJniClass");
}
protected void bindShadowClasses() {
// bind shadow JNI classes
}
}
使用重量级应用程序的应用程序的一个选项与Robolectric不兼容的是创建一个空的Application
对象并将其用于您的Robolectric测试:
像这样的东西:
public void EmptyApp extends Application {
}
然后您的测试设置可能如下所示:
@RunWith(RobolectricTestRunner.class)
@Config(application = EmptyApplication.class, manifest = "src/main/AndroidManifest.xml", sdk = 23)
由于您已引用清单,因此所有资源仍可在Context#getString(int id)
,依此类推。
正如@Jared指出的那样,@ Christopher给出的解决方案对Robolectric 2或3不起作用。
我最终使用的解决方案是添加环境变量:
ROBOLECTRIC=TRUE
到我的测试的构建配置。 (运行 - >编辑配置,环境变量)。
然后在加载有问题的库之前检查该环境变量。 例如:
class MyClass {
if(System.getenv("ROBOLECTRIC") == null) {
System.loadLibrary("libname");
}
}
显然你将无法测试任何依赖于该库的代码,但至少可以进行一些测试!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.