2015-12-04 4 views
7

私はそれが再び新しいメッセージを送るメッセージを処理するとき、Handlerを持っている非常に単純なクラスを持っている:Robolectric:私の場合は、ハンドラの実行ルーパー

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

あなたは上記を参照として、startTask()が呼び出されたときに、ハンドラは5秒後にメッセージの送信を開始します。その後、handleMessage()コールバックで、handlerは5秒の遅延でメッセージを再度送信します。これの目的は、何度かの作業(例えば、System.out.println()など)を繰り返し実行することです。

私はRobolectricで上記のクラスをテスト:

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

私はSystem.out.println()メッセージ「handling message …」5秒ごとに見ることを期待しています。しかし、私がテストを実行すると、メッセージにが一度だけ表示されます。が端末にあります。

handlerLooperは、の1つだけタスクのために実行されているように見えます。

もし私が正しいのであれば、ルーペをRobolectricで常時稼働させるにはどうしたらいいですか?私が間違っていると、なぜ私は1つのログメッセージしか見ませんか?

========== UPDATE ===========

私は私がでThread.sleep(30 * 1000);を置き換え、@rdsの答えを試してみました:

for (int i = 0; i < N; i++){ 
    shadowLooper.runToEndOfTasks(); 
} 

今N回「handling message …」が見えます。しかし、全体のテストは遅延をシミュレートしていません。 handler.sendMessageDelayed(handler.obtainMessage(…), 5000)でメッセージを送信すると、5秒間の遅延があります。そうすれば、Robolectricフレームワークはこの種の遅延メッセージをシミュレートしますか?私のテストでどのように遅れを取ることができますか?

答えて

0

runToEndOfTasks();に電話すると、この段階では1つのタスクしかありません。

テストスレッドをスリープさせる代わりに、shadowLooper.runToEndOfTasks();をN回呼び出して、ハンドラをN回呼び出す必要があります。

+0

これはより堅牢なテストでもあり、Robolectricはこのように機能します。あなたのコードが実行される時間に依存して、30秒で何回の反復が実行されるのかわからないが、 'runToEndOfTasks()'が何回呼び出されたかをテストは正確に知っている。ありがとう。 – rds

+0

runToEndOfTasks()をN回呼び出すforループによってスレッドスリープを置き換える必要があるのですか? 'for(int i = 0; i user842225

+0

私の記事の私の更新を見てください。 – user842225

0

api-webserviceからスケジュールダウンロードを実装する際に同様の問題が発生しました。ハンドラに加えてタイマーを実装しました。私はこれを使って毎日(または数秒で)あなたの仕事をしました。あなたはまた、あなたがShadowLooper#idle(long)を探しているようだ...

Timer Reference Android

0

の回数を設定することができます。これにより、ハンドラの時間を注意深く進めることができ、タスクが異なる間隔で実行されているかどうかをアサートすることができます。

関連する問題