2015-03-31 6 views
5

मेरे पास एक ऐसा फ़ंक्शन है जिसे मैं जांचना चाहता हूं जो ठीक है। कॉलबैक में चलता है। मैं Robolectrics का उपयोग करके इसका परीक्षण करने की कोशिश कर रहा हूं लेकिन कॉलबैक कभी निष्पादित नहीं होता है। मुझे लगता है कि ऐसा इसलिए है क्योंकि परीक्षण ठीक होने के बिना अनुरोध के बाद चलता है ठीक है। अब तक मैंने कोशिश की है:Robolectric के साथ okHttp अनुरोधों का परीक्षण - कॉलबैक

ShadowLooper.pauseMainLooper(); 
    Robolectric.flushBackgroundScheduler(); 
    ShadowLooper.unPauseMainLooper(); 

लेकिन यह काम नहीं किया। कोई सुझाव?

संपादित करें:

यहाँ मेरी कोड का एक उदाहरण है:

ApiClient.sendSomeDataToServer(data, callback); 

कहाँ ApiClient एक सहायक okHttp ग्राहक युक्त वर्ग है।

public static void sendSomeDataToServer(MyObject data, Callback callback){ 
    final Request request = new Request.Builder() 
      .url(API_SOME_URL) 
      .post(RequestBody.create(JSON, myObject.getAsJson().toString())) 
      .build(); 
    sHttpClient.newCall(request).enqueue(callback); 
} 

कहाँ sHttpClient एक initialised OkHttpClient है: sendSomeDataToServer API कॉल कुछ इस तरह लग रहा है।

मैं अपने परीक्षण कोड के अंदर Thread.sleep(5000) को मजबूर कर और कस्टम कॉलबैक प्रदान करके ऊपर के निष्पादन का परीक्षण कर सकता हूं। जिस कोड को मैं परीक्षण करने का प्रयास कर रहा हूं वह कॉलबैक के अंदर है। कोई सुझाव है कि मैं इसका परीक्षण कैसे कर सकता हूं? मैं वास्तव में परीक्षण ढांचे को फिट करने के लिए मुख्य कोड को बदलना नहीं चाहता हूं - दूसरा रास्ता होना चाहिए।

+0

क्या आप किसी भी निर्भरता इंजेक्शन का उपयोग करते हैं? –

उत्तर

5

मान लें कि आपके पास अगला कोड है। इंटरफ़ेस:

@GET("/user/{id}/photo") 
void listUsers(@Path("id") int id, Callback<Photo> cb); 

कार्यान्वयन:

तुम सब service इंजेक्शन के लिए service इन्स्टेन्शियशन बदलने के लिए (पैरामीटर या क्षेत्र के रूप में) की जरूरत है की
public void fetchData() { 
    RestAdapter restAdapter = new RestAdapter.Builder() 
       .setServer("baseURL")  
       .build(); 
    ClientInterface service = restAdapter.create(ClientInterface.class); 

    Callback<Photo> callback = new Callback<Photo>() { 
     @Override 
     public void success(Photo o, Response response) { 

     } 

     @Override 
     public void failure(RetrofitError retrofitError) { 

     } 
    }; 
    service.listUsers(435, callback); 
} 

पहले। मैं पैरामीटर के रूप में यह कर देगा:

public void fetchData(ClientInterface clients) { 
} 

इस पाठ के बाद काफी तुच्छ है:

@Test 
public void checkThatServiceSuccessIsProcessed() { 
    ClientInterface mockedClients = mock(ClientInterface.class); 

    activity.fetchData(mockedClients); 

    // get callback 
    ArgumentCaptor<Callback<Photo>> captor = (ArgumentCaptor<Callback<Photo>>)ArgumentCaptor.forClass(Callback.class); 
    verify(mockedInterface).listUsers(anything(), captor.capture()); 
    Callback<Photo> passedCallback = captor.value(); 
    // run callback 
    callback.success(...); 
    // check your conditions 
} 

मजाक और पुष्टि करने के लिए इस्तेमाल किया पुस्तकालय Mockito है।

जेनेरिक की वजह से कैप्चर तत्कालता के साथ एक चेतावनी होगी, लेकिन अगर आप हाथों से कैप्चर बनाने के बजाय @Captor एनोटेशन का उपयोग करेंगे तो यह ठीक हो जाएगा।

पैरामीटर इंजेक्शन सही नहीं है, खासकर गतिविधियों के मामले में। इसका उपयोग उदाहरण को सरल बनाने के लिए किया गया था। लाइब्रेरी के साथ या बिना उचित इंजेक्शन के लिए विचार करें। मैं इंजेक्शन

+0

यह मॉकिटो के बिना ऐसा करने योग्य है - बस Robolectric के साथ? – vkislicins

+0

यकीन है कि यह है। आप अपने 'क्लाइंटइंटरफेस' कार्यान्वयन को लिख सकते हैं जहां आप विधियों से कॉलबैक पकड़ सकते हैं और परीक्षणों में इसका उपयोग कर सकते हैं। लेकिन यदि 'मॉकिटो' पहले से ही आपके लिए यह प्रदान करता है तो अपनी कक्षाएं क्यों लिखें –

+0

क्या मोगिटो का हिस्सा ArgumentCaptor पर आधारित संपूर्ण समाधान नहीं है? क्या वह व्यक्ति निष्पादन और कॉलबैक के बीच में घुसपैठ नहीं कर रहा है? – vkislicins

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