简体   繁体   English

检测单元类测试 - 无法在未调用 Looper.prepare() 的线程内创建处理程序

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

Sorry I've looked at tutorials all over the place and not found the answer I'm looking for.抱歉,我已经查看了所有地方的教程,但没有找到我正在寻找的答案。 I'm following Google's Tutorial at the moment here: https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html我现在正在关注谷歌的教程: https : //developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html

I'm trying to create an Instrumented test and when I run it I'm getting the error : java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()我正在尝试创建一个 Instrumented 测试,当我运行它时出现错误: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

So my test is as follows:所以我的测试如下:

    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"));
    }
}

And I'm trying to run a method inside the main activity is as follows (this is an extract):我试图在主要活动中运行一个方法如下(这是一个摘录):

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();
    }

I presume that this is an issue because I'm not starting the service up correctly or something - I've tried using several ways, but I just get errors everywhere.我认为这是一个问题,因为我没有正确启动服务或其他东西 - 我尝试过使用多种方法,但我到处都遇到错误。 Searching on here and this error is popular, but not in relation to testing, so wondered if anyone could kindly point me in the right direction so I can test the methods in this class?在这里搜索,这个错误很流行,但与测试无关,所以想知道是否有人可以指出正确的方向,以便我可以测试此类中的方法?

The error is happening because the Looper is not correctly set up for your system under test ( MainActivity ).发生错误是因为Looper未为您的被测系统 ( MainActivity ) 正确设置。

While Activity , Fragment etc. have no-args constructors, they are designed to be instantiated by the Android OS and as such calling MainActivity = new Activity() is not enough to obtain a fully-operational death star instance complete with Handler and Looper .虽然ActivityFragment等具有无参数构造函数,但它们被设计为由 Android 操作系统实例化,因此调用MainActivity = new Activity()不足以获得完整的带有HandlerLooper的完全可操作的 死星 实例。

There are two options if you want to proceed with testing:如果您想继续测试,有两种选择:

  1. If you want to test a real instance of an Activity it will have to be an instrumented unit test ( androidTest not test ) and the @TestRule will cause the Android OS to correctly instantiate an instance of Activity:如果你想测试一个真实的 Activity 实例,它必须是一个androidTest 单元测试androidTest不是test ), @TestRule将导致 Android 操作系统正确实例化一个 Activity 实例:

     @Rule public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
  2. If you would prefer to keep writing local unit tests that run in the IDE you can use Robolectric .如果您希望继续编写在 IDE 中运行的本地单元测试,您可以使用Robolectric Robolectric will correctly stub behaviour on a shadow Activity so that you can test components that rely on Looper etc. Note there is some setup involved. Robolectric 将正确地存根影子活动的行为,以便您可以测试依赖Looper等的组件。请注意,其中涉及一些设置。

This is how I solved it.我就是这样解决的。 I ran test case on main thread using runOnMainSync .我使用runOnMainSync在主线程上运行测试用例。 Here is the comlete solution:这是完整的解决方案:

@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.

相关问题 警报对话框崩溃Android测试 - “无法在未调用Looper.prepare()的线程内创建处理程序” - Alert Dialog crashes Android test - “Can't create handler inside thread that has not called Looper.prepare()” 派生的TimerTask类中的错误:无法在未调用Looper.prepare()的线程内创建处理程序 - Error in derived TimerTask class: `Can't create handler inside thread that has not called Looper.prepare()` Android线程错误-无法在未调用Looper.prepare()的线程内创建处理程序 - Android thread error - Can't create handler inside thread that has not called Looper.prepare() 无法在警告对话框线程中未调用Looper.prepare()的线程内创建处理程序 - Can't create handler inside thread that has not called Looper.prepare() on alert dialog thread 无法在未在AsyncTask for ProgressDialog中调用Looper.prepare()的线程内创建处理程序 - Can't create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog java.lang.RuntimeException:无法在尚未调用Looper.prepare()的线程内创建处理程序 - java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() java.lang.RuntimeException:无法在尚未调用 Looper.prepare() 的线程内创建处理程序错误 - java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() Error 无法在 AsyncTask 中未调用 Looper.prepare() 的线程内创建处理程序 - Can't create handler inside thread that has not called Looper.prepare() in AsyncTask 无法在未调用Looper.prepare()Android的线程内创建处理程序 - Can't create handler inside thread that has not called Looper.prepare() Android java.lang.RuntimeException:无法在未在Android中调用Looper.prepare()的线程内创建处理程序 - java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() in Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM