簡體   English   中英

檢測單元類測試 - 無法在未調用 Looper.prepare() 的線程內創建處理程序

[英]Instrumented Unit Class Test - Can't create handler inside thread that has not called Looper.prepare()

抱歉,我已經查看了所有地方的教程,但沒有找到我正在尋找的答案。 我現在正在關注谷歌的教程: https : //developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html

我正在嘗試創建一個 Instrumented 測試,當我運行它時出現錯誤: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

所以我的測試如下:

    package testapp.silencertestapp;

import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class MainActivityTest {

    private MainActivity testMain;

    @Before
    public void createActivity(){
        testMain = new MainActivity();
    }

    @Test
    public void checkFancyStuff(){
        String time = testMain.createFancyTime(735);

        assertThat(time, is("07:35"));
    }
}

我試圖在主要活動中運行一個方法如下(這是一個摘錄):

public class MainActivity extends AppCompatActivity {

    private TimePicker start;
    private TimePicker end;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        start = (TimePicker) findViewById(R.id.startPicker);
        end = (TimePicker) findViewById(R.id.endPicker);
}

 String createFancyTime(int combinedTime) {

        StringBuilder tempString = new StringBuilder(Integer.toString(combinedTime));
        if(tempString.length()==4){
            tempString = tempString.insert(2, ":");
        }
        else if (tempString.length()==3){
            tempString = tempString.insert(1, ":");
            tempString = tempString.insert(0, "0");
        }
        else if(tempString.length()==2){
            tempString = tempString.insert(0, "00:");
        }
        else if(tempString.length()==1){
            tempString = tempString.insert(0, "00:0");
        }
        return tempString.toString();
    }

我認為這是一個問題,因為我沒有正確啟動服務或其他東西 - 我嘗試過使用多種方法,但我到處都遇到錯誤。 在這里搜索,這個錯誤很流行,但與測試無關,所以想知道是否有人可以指出正確的方向,以便我可以測試此類中的方法?

發生錯誤是因為Looper未為您的被測系統 ( MainActivity ) 正確設置。

雖然ActivityFragment等具有無參數構造函數,但它們被設計為由 Android 操作系統實例化,因此調用MainActivity = new Activity()不足以獲得完整的帶有HandlerLooper的完全可操作的 死星 實例。

如果您想繼續測試,有兩種選擇:

  1. 如果你想測試一個真實的 Activity 實例,它必須是一個androidTest 單元測試androidTest不是test ), @TestRule將導致 Android 操作系統正確實例化一個 Activity 實例:

     @Rule public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
  2. 如果您希望繼續編寫在 IDE 中運行的本地單元測試,您可以使用Robolectric Robolectric 將正確地存根影子活動的行為,以便您可以測試依賴Looper等的組件。請注意,其中涉及一些設置。

我就是這樣解決的。 我使用runOnMainSync在主線程上運行測試用例。 這是完整的解決方案:

@RunWith(AndroidJUnit4::class)
class AwesomeViewModelTest {

    @Test
    fun testHandler() {

        getInstrumentation().runOnMainSync(Runnable {
            val context = InstrumentationRegistry.getInstrumentation().targetContext

          // Here you can call methods which have Handler

       
        })
    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM