我正在将UnitTests改造为现有的应用程序.当我运行这个简单的单元测试时
import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import static junit.framework.Assert.assertTrue; @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, packageName = "com.blah.blah" ) public class TestThis { @Test public void blah(){ assertTrue(true); } }
我收到这个错误
java.lang.IllegalArgumentException: INTERNET permission is required. at com.segment.analytics.Analytics$Builder.(Analytics.java:585) at com.segment.analytics.Analytics.with(Analytics.java:115) at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140) at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240) 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.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 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) java.lang.RuntimeException: java.lang.IllegalArgumentException: INTERNET permission is required. at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:244) 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.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.IllegalArgumentException: INTERNET permission is required. at com.segment.analytics.Analytics$Builder. (Analytics.java:585) at com.segment.analytics.Analytics.with(Analytics.java:115) at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140) at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433) at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240)
我的第一个假设是,robolectric没有得到清单,但它似乎在那里.我有什么基本的东西吗?
对不起,我写这篇文章的时候很匆忙,应该补充一些细节
我在清单中确实有这个
我在阅读本页后尝试明确设置清单 Robolectric junit测试 - 缺少互联网许可
另一个更新,问题是onCreate()中触发的http调用
public class TestApp extends Application { @Override public final void onCreate() { super.onCreate(); singleton = this; if (!BuildConfig.DEBUG) { Fabric.with(this, new Crashlytics()); } loadData(); // The next line makes the http call Analytics.with(getApplicationContext()).identify("userId", null, null); RequestQueues.initInstance(singleton); } }
有什么想法吗?我可以补充一下
if (notTest) { com.segment.analytics.Analytics.with(getApplicationContext()).identify("userId", }
但不愿意
显然,当使用robolectric运行单元测试时,不会启用权限.检查Segment lib,它会检查Internet权限,如下所示:
/** Returns true if the application has the given permission. */ public static boolean hasPermission(Context context, String permission) { return context.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED; }
但正如所说,运行测试你的应用程序将没有互联网权限(但你可以进行互联网调用)你可以通过给予影子应用程序的互联网权限然后在段lib中使用此上下文来解决这个问题.
将此方法添加到TestApp
protected Context instance() { ShadowApplication shadowApp = Shadows.shadowOf(this); shadowApp.grantPermissions("android.permission.INTERNET"); return shadowApp.getApplicationContext(); }
并将您的代码更改为此
Analytics.with(instance()).identify("userId", null, null);
希望它对你有所帮助.