Robolectric測試報錯集合

1、JsonObject not mocked

這是因爲JsonObject屬於Android SDK,我們如果做單元測試需要用到它,那就需要引入json.jar包。所以,

第一步:下載json.jar包

下載地址:https://mvnrepository.com/artifact/org.json/json

隨便選一個日期,我這裏下載最新2018年8月13號發佈的,如下圖所示:

選擇下圖中的View All會進入一個新的頁面,點擊|“json-20180813.jar”下載。

第二步:把jar包放進要測試的項目即可。

 

2、報錯Error:(125, 0) Could not set unknown property 'includeAndroidResources'

本地配置:AS 3.0.1 + Robolectric 3.8+gradle 4.4-rc-3+sdk25

報錯原因:build.gradle裏面是

classpath 'com.android.tools.build:gradle:2.3.3'

但includeAndroidResources是3.0+纔有,所以改成

classpath 'com.android.tools.build:gradle:3.0.1'

再次運行,問題解決。

 

3.java.lang.IllegalStateException: this method should only be called by Robolectric

原因是sdk版本配置有誤,在我們設置了sdk時,會先下載對應的robolectric.jar包並安裝。如果當前安裝的是sdk25對應的jar包,但用的是sdk=27就會報這個錯。

 

4、Unable to resolve artifact: Missing: ---------- 1) org.robolectric:android-all:jar:8.1.0-robolectric-r4458339 Try downloading the file manually from the project website. Then, install it using the command: mvn install:install-file -DgroupId=org.robolectric -DartifactId=android-all -Dversion=8.1.0-robolectric-r4458339 -Dpackaging=jar -Dfile=/path/to/file Alternatively, if you host your own repository you can deploy the file there: mvn deploy:deploy-file -DgroupId=org.robolectric -DartifactId=android-all -Dversion=8.1.0-robolectric-r4458339 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id] Path to dependency: 1) org.apache.maven:super-pom:pom:2.0 2) org.robolectric:android-all:jar:8.1.0-robolectric-r4458339 ---------- 1 required artifact is missing. for artifact: org.apache.maven:super-pom:pom:2.0 from the specified remote repositories: nexus (http://116.10.196.222:8081/nexus/content/groups/public/)

解決方法:其實上面說得很清楚了,下載對應的jar包然後安裝。具體如下:

第一步:https://oss.sonatype.org/content/groups/public/org/robolectric/android-all/8.1.0-robolectric-r4458339/

在該路徑下找到我們所要的那個jar包,然後“cmd"->輸入”mvn install:install-file -DgroupId=org.robolectric -DartifactId=android-all -Dversion=8.1.0-robolectric-r4458339 -Dpackaging=jar -Dfile=/path/to/file",其中/path/to/file是我們下載下來的這個jar包的路徑。

當出現下圖時說明安裝成功。

 

5、java.lang.NoClassDefFoundError: Could not initialize class io.objectbox.internal.NativeLibraryLoader

和 java.lang.UnsatisfiedLinkError: Native Library D:\xxx\app\objectbox-windows-x64.dll already loaded in another classloader

sdk設置不正確,要和我們安裝的robolectric.jar包版本對應

6、Could not open env for DB (error code -30789)

7、java.lang.RuntimeException: Method i in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details. at android.util.Log.i(Log.java)

很明顯,這個是說我們用到了android包中的方法,也就是Log.i,替換成ShadowLog.i方法即可。

8、java.lang.IllegalArgumentException: Don't know what to do with dataSource org.robolectric.shadows.util.DataSource@aa97c9b1 - either add an exception with addException() or media info with addMediaInfo()

這個問題定位在一個播放asserts中某個MP3文件的位置,一開始我以爲是找不到這個MP3文件,可是文件明明存在呀。接着我又想會不會是asserts文件夾是錯誤的呢?於是我在RobolectricTestRunner.class中打了斷點去獲取相關的配置新,得到下圖這個結果:

很明顯,這就是我本地的build中對應的文件路徑,並且那個MP3文件也是存在的。

最後我找到了真正的原因:那就是我當前所用的sdk是27,所以需要去獲取文件的讀寫權限,因爲沒有獲取到權限,所以纔會出現這個錯誤。

9、Robolectric測試類內部的自定義廣播接收者報錯:xxx is not an enclosing class,這個xxx就是我的自定義廣播名稱。這是什麼原因呢?

我最開始的代碼是這樣子寫的:

@Test
public void onCreate() throws Exception {
    ShadowApplication shadowApplication = ShadowApplication.getInstance();
    Intent intent = new Intent(UPDATE_COLLECT_MAIN);

    //測試是否註冊廣播接收者
    assertTrue(shadowApplication.hasReceiverForIntent(intent));
    //以下測試廣播接收者的處理邏輯是否正確
    CollectListPresenter.CollectListReceiver mReceiver = new CollectListPresenter.CollectListReceiver();
    mReceiver.onReceive(RuntimeEnvironment.application, intent);
    //...操作測試忽略
}


// 這是測試類中的自定義廣播接收者的代碼
public class CollectListReceiver extends BroadcastReceiver {

    // 自定義一個廣播接收器
    @Override
    public void onReceive(Context context, Intent intent) {
        //...接受廣播後的一些操作
    }
}

其中CollectListPresenter就是這個測試類,而CollectListReceiver自然就是在這個測試類內部的自定義廣播接收者。乍一看和我們平時new一個對象沒啥區別嘛,實際上這是不對的。所以後面我改成了下面的測試代碼,這裏只是做個記錄:

@Test
public void onCreate() throws Exception {
    ShadowApplication shadowApplication = ShadowApplication.getInstance();
    Intent intent = new Intent(UPDATE_COLLECT_MAIN);

    //測試是否註冊廣播接收者
    assertTrue(shadowApplication.hasReceiverForIntent(intent));
    //以下測試廣播接收者的處理邏輯是否正確
    CollectListPresenter.CollectListReceiver mReceiver = presenter.new CollectListReceiver();
    mReceiver.onReceive(RuntimeEnvironment.application, intent);
    //...操作測試忽略
}

其中上面的presenter是我們事先new 好的CollectListPresenter對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章