我使用Robolectric进行单元测试,我的项目中有Google Play服务.直到昨天,当Google Play服务更新为新版本时,此工作正常.我收到此错误:
- java.lang.NullPointerException
- at com.google.android.gms.common.GooglePlayServicesUtil.zzh(Unknown Source)
- at com.google.android.gms.common.GooglePlayServicesUtil.zzd(Unknown Source)
- at com.google.android.gms.common.GoogleApiAvailability.isGooglePlayServicesAvailable(Unknown Source)
- at com.google.android.gms.common.api.zzg$zze.zznn(Unknown Source)
- at com.google.android.gms.common.api.zzg$zzi.run(Unknown Source)
- at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
- at java.util.concurrent.FutureTask.run(FutureTask.java:266)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
- at java.lang.Thread.run(Thread.java:745)
- Process finished with exit code 255
似乎没有调用Shadow类,调用GooglePlayServicesUtil给出NullPointerException.有没有人见过这个?
我甚至不在测试中使用Google Play服务.
解决方法
我添加了下一个解决方法,它工作正常:
>将所有PlayServices的相关代码解压缩到Utility类(在我的例子中,它只是可用性检查):
- public class PlayServicesUtils {
- private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
- public static final int AVAILABLE = 1;
- public static final int ERROR_RESOLVABLE = 2;
- public static final int ERROR_UNRESOLVABLE = 3;
- @IntDef({AVAILABLE,ERROR_RESOLVABLE,ERROR_UNRESOLVABLE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface PlayServicesAvailability {
- }
- @PlayServicesAvailability
- public static int checkPlayServices(@NonNull Activity activity) {
- GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
- int resultCode = apiAvailability.isGooglePlayServicesAvailable(activity);
- if (resultCode != ConnectionResult.SUCCESS) {
- if (apiAvailability.isUserResolvableError(resultCode)) {
- apiAvailability.getErrorDialog(activity,resultCode,PLAY_SERVICES_RESOLUTION_REQUEST).show();
- return PlayServicesUtils.ERROR_RESOLVABLE;
- } else {
- CLog.e(Constants.TAG,"This device does not support Google Play services.");
- return PlayServicesUtils.ERROR_UNRESOLVABLE;
- }
- }
- return PlayServicesUtils.AVAILABLE;
- }
- }
>为此Utility类实现阴影:
- @Implements(PlayServicesUtils.class)
- public class ShadowPlayServicesUtils {
- @Implementation
- @PlayServicesUtils.PlayServicesAvailability
- public static int checkPlayServices(@NonNull Activity activity) {
- return PlayServicesUtils.AVAILABLE;
- }
- }
>为您的测试类(或基类测试类)添加阴影:
- @Ignore
- @RunWith(TestRunner.class)
- @Config(
- sdk = 18,constants = BuildConfig.class,shadows = {
- ShadowPlayServicesUtils.class
- }
- )
- public abstract class BaseTest {
- // some code,maybe
- }
>将您的影子添加到TestRunner的InstrumentationConfiguration创建中:
- public class TestRunner extends RobolectricGradleTestRunner {
- public TestRunner(Class<?> klass) throws InitializationError {
- super(klass);
- }
- @Override
- public InstrumentationConfiguration createClassLoaderConfig() {
- InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
- builder.addInstrumentedClass(PlayServicesUtils.class.getName());
- return builder.build();
- }
- }
原始答案:
我在Robolectric问题跟踪器上找到了similar issue,并在那里提供了解决方法 – 工作!
只需强制成功初始化Google Play服务:
- @Before public void setUp() {
- // force success every time
- ShadowGooglePlayServicesUtil.setIsGooglePlayServicesAvailable(ConnectionResult.SUCCESS);
- }
编辑: