[英]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
.虽然
Activity
、 Fragment
等具有无参数构造函数,但它们被设计为由 Android 操作系统实例化,因此调用MainActivity = new Activity()
不足以获得完整的带有Handler
和Looper
的完全可操作的
死星
实例。
There are two options if you want to proceed with testing:如果您想继续测试,有两种选择:
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);
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.