Java – robolectric: the looper that runs the handler in my case
I have a very simple class. It has a handler. When it processes a message, it sends a new message again:
public class MyRepeatTask{ … public void startTask() { // send message with delay 5 sec handler.sendMessageDelayed(handler.obtainMessage(…),5000); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // I put a log for unit test System.out.println(“handling message …”); // send message with delay again handler.sendMessageDelayed(handler.obtainMessage(…),5000); } } }
As shown above, when starttask () is called, the handler will start sending messages within 5 seconds Then, in the handlemessage () callback, the handler sends the message again with a delay of 5 seconds The purpose of this is to repeat certain tasks (such as system. Out. Println())
I use robolectric to test the above class:
@RunWith(RobolectricTestRunner.class) public class MyRepeatTaskTest { @Test public void testStartTask() { MyRepeatTask task = new MyRepeatTask(); task.startTask(); // run looper of ‘handler’ in task ShadowLooper shadowLooper = Shadows.shadowOf(task.handler.getLooper()); shadowLooper.runToEndOfTasks(); // sleep for 30 seconds Thread.sleep(30 * 1000); } }
I want to see system every five seconds out. Println() message "process message..." However, when I run the test, I only see a message in the terminal once
It seems that the looper of the handler runs only one task and then stops
If I'm right, how do I keep the bending needle running all the time in robolectric? If I'm wrong, why do I only see one log message?
==========Renew===========
I tried @ RDS's answer, and I replaced thread sleep(30 * 1000); By:
for (int i = 0; i < N; i++){ shadowLooper.runToEndOfTasks(); }
Now I can see "process message..." n times However, the whole test did not simulate the delay Use handler Sendmessagedelayed (handler. Obtainmessage (...), 5000) when sending a message, I have a delay of 5 seconds. Does the robolectric framework not simulate this delayed message at all? How do I delay testing?
Solution
The problem is when you call runtoendoftasks(); There is only one task at this stage
You should call shadowlooper runToEndOfTasks(); Instead of letting the test thread sleep N calls to your handler n times