2015-08-17 50 views
7

我使用Robolectric進行單元測試,我在我的項目中使用了Google Play服務。這工作得很好,直到昨天,當Google Play服務更新到新版本。我得到這個錯誤:Robolectric與新版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服務。

+0

NullPointerException主要是當類沒有被映射時。你什麼時候收到這個錯誤?在測試用例運行期間還是在測試之前加載應用程序配置時? – Kanishk

+0

我知道這不是陰影。 GooglePlayServicesUtil有一個影子類,直到昨天它運行良好,它在昨天之前被遮蔽了。我試圖找出Robolectric是否依賴於特定版本的GPS,但沒有發現。 – Christine

+0

我認爲您可以在[Roblectric]問題[此處](https://github.com/robolectric/robolectric/issues)或Android問題跟蹤器[此處](https://code.google.com/p/android/issues/list) – bjiang

回答

4

我已經添加了接下來的一種方法,它工作正常:

  1. 提取所有PlayServices'相關代碼的實用工具類(對我來說,這只是可用性檢查):

    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; 
        } 
    } 
    
  2. 此效用類的工具陰影:

    @Implements(PlayServicesUtils.class) 
    public class ShadowPlayServicesUtils { 
    
        @Implementation 
        @PlayServicesUtils.PlayServicesAvailability 
        public static int checkPlayServices(@NonNull Activity activity) { 
         return PlayServicesUtils.AVAILABLE; 
        } 
    } 
    
  3. 添加陰影您的測試類(或基礎水平測試類):

    @Ignore 
    @RunWith(TestRunner.class) 
    @Config(
         sdk = 18, 
         constants = BuildConfig.class, 
         shadows = { 
           ShadowPlayServicesUtils.class 
         } 
    ) 
    public abstract class BaseTest { 
        // some code, maybe 
    } 
    
  4. 添加你的影子的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在那裏提供 - 工作!

就迫使谷歌的成功初始化播放服務:

@Before public void setUp() { 
    // force success every time 
    ShadowGooglePlayServicesUtil.setIsGooglePlayServicesAvailable(ConnectionResult.SUCCESS); 
} 

編輯:

但還有另一種issue Play服務8.3和8.4。而這個問題仍然沒有解決。

+0

謝謝。直到他們用8.4版本解決問題的時候,這個工作很棒! –

+0

@ShobhitPuri歡迎您! – Oleksandr

+0

我無法使用這個解決方案,因爲最新的robolectric改變了API,所以它不會編譯(我們的測試取決於新版本)。這裏是我的問題,關於如何實現這個新的,請看看:https://stackoverflow.com/questions/48123570/ – Gabor