2011-09-29 34 views
5

नीचे मेरे आवेदन का सरलीकृत सेटअप है। इसमें एक वर्ग फूबर है जो डेटा लाने के लिए एक मुखौटा विधि पर कॉल करता है। इसके बाद मुखौटा वास्तव में डेटा प्राप्त करने के लिए एक वेब सेवा पर कॉल करता है और फिर डेटा को थोड़ा सा जोड़ता है और फिर इसे फूबर पर लौटाता है।एसिंक विधि कॉल का परीक्षण

अब क्योंकि वेब सेवा चलाने के लिए अच्छा समय ले सकता है, मुखौटा को विधि कॉल असीमित होने की आवश्यकता है। इसलिए मुखौटा की विधि में वापसी मान नहीं है, बल्कि इसके बजाय, विधि कॉलबैक ऑब्जेक्ट का उपयोग करती है। उदाहरण देखें और नीचे पढ़ना जारी रखें।

public class Foobar { 
    private List<DTO> dtos; 

    @Autowired 
    private Facade facade; 

    public void refresh() { 
     facade.refreshFoobar(new CallBack() { 
      public void dataFetched(List<DTO> dtos) { 
       setDtos(dtos); 
      } 

     }); 
    }  

    public void setDtos(List<DTO> dtos) { 
     this.dtos = dtos; 
    } 
} 


public class Facade { 

    ... 

    public void refreshFoorbar(CallBack cb) { 
     // Fetch data from a web service 
     List<DTO> dtos = webService.getData(); 
     // Manipulate DTOs 
     .... 
     // call on the callback method 
     cb.dataFecthed(dtos); 
    } 

} 

मैं मुखौटा की विधि अतुल्यकालिक करने के दो तरीके होते हैं, या तो स्वयं एक धागा बनाने के द्वारा या स्प्रिंग्स @Async एनोटेशन का उपयोग करके।

public class Facade { 

    public void refreshFoorbar(CallBack cb) { 
     new Thread() { 

      @Override 
      public void run() { 
       .... 
      } 

     }.start(); 

    } 
} 

// ... OR ... 

public class Facade { 

    @Async 
    public void refreshFoorbar(CallBack cb) { 
     ....  
    } 
} 

मेरी समस्या यह है कि अब मुझे विधि कॉल की इस श्रृंखला के लिए एकीकरण परीक्षण लिखने की आवश्यकता है। मुझे लगता है कि जब एकीकरण परीक्षण चलाया जाता है तो मुझे एसिंक मुखौटा कॉल को तुल्यकालिक होने की आवश्यकता होती है, अन्यथा मुझे यह सुनिश्चित नहीं होगा कि मैं उचित आवेषण कब कर सकता हूं। विधि कॉल सिंक्रोनस बनाने का एकमात्र विचार मैन्युअल रूप से हैंडल किए गए धागे का उपयोग करना और थ्रेडिंग सशर्त बनाना (इसलिए, परीक्षण उद्देश्यों के लिए, मेरे पास एक अगर खंड है जो निर्धारित करता है कि मुखौटा विधि को अलग थ्रेड में चलाया जाना चाहिए या नहीं)।

हालांकि, मुझे एहसास है कि मेरी समस्या का बेहतर समाधान हो सकता है, चाहे यह मुझे सिंक्रोनस के लिए विधि को मजबूर करने का एक बेहतर तरीका हो, उदाहरण के लिए वसंत के साथ, या किसी भी तरह से मल्टीथ्रेडिंग का परीक्षण करके।

यह वह जगह है जहां मुझे आपके सुझावों की आवश्यकता है, आप मेरी समस्या का समाधान कैसे करेंगे? नोट, मैं दोनों इकाई और एकीकरण परीक्षणों के लिए जूनिट का उपयोग कर रहा हूं।

+0

मुझे नहीं पता कि यह सही तरीका है या नहीं। आम तौर पर एसिंक्रोनस स्थितियों के लिए परीक्षण केवल एसिंक्रोनस कार्य लॉन्च कर रहा है, थोड़ी देर प्रतीक्षा करें और कार्य पूरा हो गया है या नहीं। – SJuan76

उत्तर

6

जब जुनीट इस तरह की चीजें परीक्षण करते हैं, तो मैं CountDownLatch के साथ एक परीक्षण कॉलबैक का उपयोग करता हूं जो कॉलबैक द्वारा गिना जाता है और परीक्षण विधि द्वारा await() एड।

private static class TestingCallback implements Callback { 
    private final CountDownLatch latch; 
    public TestingCallback(CountDownLatch latch) { 
     this.latch = latch; 
    } 
    @Override public void onEvent() { 
     this.latch.countDown(); 
    } 
} 

@Test 
public void testCallback() { 
    final CountDownLatch latch = new CountDownLatch(1); 

    classUnderTest.execute(new TestCallback(latch)); 

    assertTrue(latch.await(30, TimeUnit.SECONDS)); 
} 

कॉलबैक परीक्षण के अंतर्गत कोड (अतुल्यकालिक रूप से) शुरू हो जाती है, तो कुंडी रिटर्न true और परीक्षण गुजरता है। यदि कॉलबैक नहीं बुलाया जाता है, तो तीस सेकंड के बाद परीक्षण का समय और दावा विफल हो जाता है।

12

सरल समाधान इस तरह की एक भविष्य वस्तु वापस जाने के लिए,

@Async 
public Future<String> refreshFoorbar(CallBack cb) { 
    yourHeavyLifting(); //asynchronous call 
    return new AsyncResult<String>("yourJobNameMaybe"); 
} 

और अपने परीक्षण में, भविष्य में संदर्भ लेने के लिए और get() विधि कॉल किया जाएगा।

future.get(); // if its not already complete, waits for it to complete 
assertTrue(yourTestCondition) 

यह blog post नमूना दिखाता है।

+0

इसे देखें यदि यह http://www-01.ibm.com/support/knowledgecenter/SSCKBL_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/tejb_clientcode.html की सहायता करता है –

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