lou*_*uio 6 multithreading android unit-testing handler
我在Android中进行单元测试时遇到问题.
我的对象MyObject有一个start()
这样的方法:
public void start() {
final Handler onStartHandler = new Handler();
new Thread() {
@Override
public void run() {
super.run();
onStartHandler.post(new Runnable() {
@Override
public void run() {
mIsRunning = true;
onStart();
}
});
}
}.start();
}
Run Code Online (Sandbox Code Playgroud)
我想测试onStart()是否被调用.所以我尝试了类似的东西:
public void testOnStartIsCalled() {
assertFalse("onStart() should not be called", mMyObject.isRunning());
mMyObject.start();
assertTrue("onStart() should be called", mMyObject.isRunning());
mMyObject.stop();
assertFalse("onStop() should be called", mMyObject.isRunning());
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,我想这是因为它在Handler和一个新线程中.
我的测试类扩展了AndroidTestCase.我该怎么办 ?这种情况的最佳做法是什么?
问候.
当我处理测试一些多线程代码时,我试图让程序尽可能多地采用自然流程.另外,我避免使用睡眠陈述,因为你没有得到任何保证,你选择的睡眠间隔足以让你的测试对象完成它正在做的事情; 你经常最终不得不选择太大的睡眠间隔,这会迫使你的测试用例执行得慢得多.
我建议您尝试将一些代码添加到您正在测试的类中,在这种情况下MyObject
,只要发生某些事情就会调用侦听器.看来你已经有了回调方法onStart()
和onStop()
(如果那些是事件/回调),所以应该调用它们,你应该使用它们来控制你的测试流程.当您收到onStart()
活动时,您应该打电话stop()
并等待onStop()
活动.
首先,您有冗余代码:
public void start() {
final Handler onStartHandler = new Handler();
new Thread() {
@Override
public void run() {
super.run();
onStartHandler.post(new Runnable() {
@Override
public void run() {
mIsRunning = true;
onStart();
}
});
}
}.start();
}
Run Code Online (Sandbox Code Playgroud)
启动一个新线程来调用onStart()
或调度Handler的线程队列上的runnable.
版本1-删除处理程序,只需让代码在新线程中执行:
public void start() {
new Thread() {
@Override
public void run() {
super.run();
mIsRunning = true;
onStart();
}
}.start();
}
Run Code Online (Sandbox Code Playgroud)
版本2-仅使用处理程序异步执行回调:
public void start() {
final Handler onStartHandler = new Handler();
onStartHandler.post(new Runnable() {
@Override
public void run() {
mIsRunning = true;
onStart();
}
});
}
Run Code Online (Sandbox Code Playgroud)
第二:我注意到如果你没有一个Looper,那么你发布的任何内容Handler
都会被忽略(因此它永远不会被调用).有关Looper-Handler模式的更多信息,请参阅文章:Android Guts:Loopers和Handler简介.的Looper
和Handler
都应该被连接到同一个线程(通常是主线程).另外,如果您在Handler
单独的线程上创建Looper
,那么您将遇到同样的问题:您发布的任何内容都Handler
将被忽略.
这里有一些关于loopers和handlers的更好的问题和文章:
Looper,Handler和MessageQueue之间的关系如下所示: