2015-12-04 9 views
7

में चलाने के हैंडलर के looper मैं, एक बहुत ही सरल वर्ग है जो एक 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 सेकंड देखने की उम्मीद। हालांकि, जब मैं अपना परीक्षण चलाता हूं, तो मुझे केवल संदेश टर्मिनल में दिखाई देता है।

ऐसा लगता है कि handler के Looper के लिए ही एक कार्य समाप्त हो गया है लग रहा है, तो यह बंद कर दिया।

अगर मैं सही हूँ, कैसे Robolectric में हर समय चल रहा looper रखने के लिए? अगर मैं गलत हूं, तो मुझे केवल एक लॉग संदेश क्यों दिखाई देता है?

========== अद्यतन ===========

मैंने कोशिश की @rds के जवाब, मैं द्वारा Thread.sleep(30 * 1000); लाए गए:

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

अब मैं एन बार देख सकता हूं "handling message …"। लेकिन, पूरा परीक्षण देरी अनुकरण नहीं कर रहा है। handler.sendMessageDelayed(handler.obtainMessage(…), 5000) के साथ संदेश भेजते समय मेरे पास 5 सेकंड की देरी है, क्या यह है कि रोबोलेक्ट्रिक फ्रेमवर्क इस तरह के देरी संदेश को अनुकरण नहीं करता है ??? मेरे परीक्षण में देरी कैसे हो सकती है?

उत्तर

0

समस्या है जब आप runToEndOfTasks(); फोन वहाँ इस स्तर पर केवल एक ही कार्य है।

इसके बजाय परीक्षण धागा नींद दे की, तो आप अपने हैंडलर के एन कॉल कर पाने के shadowLooper.runToEndOfTasks(); N बार फोन करना चाहिए।

+0

यह भी एक और अधिक मजबूत परीक्षण है, और यही कारण है कि Robolectric इस तरह काम करता है। आपके कोड को निष्पादित करने के समय के आधार पर, आप नहीं जानते कि 30 सेकंड में कितने पुनरावृत्तियों को निष्पादित किया जाएगा, लेकिन परीक्षणों को पता है कि कितनी बार 'runToEndOfTasks() 'कहा जाता था। – rds

+0

धन्यवाद। क्या आपका मतलब है कि मुझे थ्रेड नींद को एक लूप द्वारा प्रतिस्थापित करना चाहिए जो RunToEndOfTasks() एन बार कॉल करता है? 'के लिए (int i = 0; i <एन -1, i ++) {shadowLooper.runToEndOfTasks();}' – user842225

+0

कृपया मेरे पोस्ट में अपने को अपडेट हुआ। – user842225

0

मैं जब api-वेब सेवा से एक अनुसूचित डाउनलोड को लागू इसी तरह की समस्याओं बारे में जाना। मैंने एक हैंडलर के अलावा इसके बजाय एक टाइमर लागू किया। मैंने इसे हर दिन एक कार्य करने के लिए इस्तेमाल किया (या आपके मामले में कई सेकंड में)। आप यह भी समय की संख्या ...

Timer Reference Android

0

ऐसा लगता है आप ShadowLooper#idle(long) लिए देख रहे हैं निर्धारित कर सकते हैं। यह आपको हैंडलर के समय को सावधानी से आगे बढ़ाने की अनुमति देगा और जोर देगा कि कार्य अलग-अलग अंतराल पर चल रहा है या नहीं।

संबंधित मुद्दे