2012-04-27 19 views
7

मैं एंड्रॉइड जुनीट टेस्ट केस कैसे बना सकता हूं जो किसी गतिविधि के भीतर उत्पन्न इरादे की सामग्री का परीक्षण करता है?मैं एक गतिविधि से लॉन्च/भेजे गए इरादे का परीक्षण कैसे कर सकता हूं?

मुझे एक ऐसी गतिविधि मिली है जिसमें एक संपादन टेक्स्ट विंडो है, और जब उपयोगकर्ता आवश्यक डेटा दर्ज करना समाप्त कर लेता है, तो गतिविधि एक इरादा सेवा के लिए एक इरादा लॉन्च करती है जो डेटा रिकॉर्ड करती है और एप्लिकेशन प्रक्रिया के साथ जारी होती है। यहाँ वर्ग मैं परीक्षण करना चाहते हैं, OnEditorActionListener/PasscodeEditorListener एक अलग वर्ग के रूप में बनाया जाता है:

public class PasscodeActivity extends BaseActivity { 
    EditText     m_textEntry = null; 
    PasscodeEditorListener  m_passcodeEditorListener = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.passcode_activity); 

     m_passcodeEditorListener = new PasscodeEditorListener(); 
     m_textEntry = (EditText) findViewById(R.id.passcode_activity_edit_text); 
     m_textEntry.setTag(this); 
     m_textEntry.setOnEditorActionListener(m_passcodeEditorListener); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     /* 
     * If we're covered for any reason during the passcode entry, 
     * exit the activity AND the application... 
     */ 
     Intent finishApp = new Intent(this, CoreService.class); 
     finishApp.setAction(AppConstants.INTENT_ACTION_ACTIVITY_REQUESTS_SERVICE_STOP); 
     startService(finishApp); 
     finish(); 
    } 

} 



class PasscodeEditorListener implements OnEditorActionListener{ 
    @Override 
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
     PasscodeActivity activity = (PasscodeActivity) v.getTag(); 
     boolean imeSaysGo = ((actionId & EditorInfo.IME_ACTION_DONE)!=0)?true:false; 
     boolean keycodeSaysGo = ((null != event) && 
       (KeyEvent.ACTION_DOWN == event.getAction()) && 
       (event.getKeyCode() == KeyEvent.KEYCODE_ENTER))?true:false; 

     if (imeSaysGo || keycodeSaysGo){ 
      CharSequence seq = v.getText(); 
      Intent guidEntry = new Intent(activity, CoreService.class); 
      guidEntry.setAction(AppConstants.INTENT_ACTION_PASSCODE_INPUT); 
      guidEntry.putExtra(AppConstants.EXTRA_KEY_GUID, seq.toString()); 
      activity.startService(guidEntry); 
      return true; 
     } 
     return false; 
    } 
} 

मैं गतिविधि द्वारा उत्पन्न दो संभावित आउटबाउंड उद्देश्य कैसे रोकना और उनकी सामग्री की पुष्टि कर सकते हैं?

धन्यवाद

+0

क्या आप सिमुलेटर का उपयोग कर रहे हैं? शायद मुझे कुछ याद आ रहा है, लेकिन क्या आप इसे इस तरह से जांच नहीं सकते? – Nick

+0

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

उत्तर

6

मैं एक वेबसाइट की मदद से ContextWrapper उपयोग करने के लिए कैसे लगा।

ContextWrapper का उपयोग करें और सभी उद्देश्यों को ओवरराइड करें। मेरे सभी गतिविधि परीक्षणों के लिए सामान्यीकरण, मैंने ActivityUnitTestCase क्लास को बढ़ाया और समाधान को एक शिम के रूप में कार्यान्वित किया। आनंद लें:

import android.app.Activity; 
import android.app.Instrumentation; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.ContextWrapper; 
import android.content.Intent; 
import android.test.ActivityUnitTestCase; 

public class IntentCatchingActivityUnitTestCase<T extends Activity> extends ActivityUnitTestCase<T> { 

    protected Activity m_activity; 
    protected Instrumentation m_inst; 
    protected Intent[] m_caughtIntents; 
    protected IntentCatchingContext m_contextWrapper; 

    protected class IntentCatchingContext extends ContextWrapper { 
     public IntentCatchingContext(Context base) { 
      super(base); 
     } 

     @Override 
     public ComponentName startService(Intent service) { 
      m_caughtIntents = new Intent[] { service }; 
      return service.getComponent(); 
     } 

     @Override 
     public void startActivities(Intent[] intents) { 
      m_caughtIntents = intents; 
      super.startActivities(intents); 
     } 

     @Override 
     public void startActivity(Intent intent) { 
      m_caughtIntents = new Intent[] { intent }; 
      super.startActivity(intent); 
     } 

     @Override 
     public boolean stopService(Intent intent) { 
      m_caughtIntents = new Intent[] { intent }; 
      return super.stopService(intent); 
     } 
    } 

    // --// 
    public IntentCatchingActivityUnitTestCase(Class<T> activityClass) { 
     super(activityClass); 
    } 

    protected void setUp() throws Exception { 
     super.setUp(); 
     m_contextWrapper = new IntentCatchingContext(getInstrumentation().getTargetContext()); 
     setActivityContext(m_contextWrapper); 
     startActivity(new Intent(), null, null); 
     m_inst = getInstrumentation(); 
     m_activity = getActivity(); 
    } 

    protected void tearDown() throws Exception { 
     super.tearDown(); 
    } 

} 
+0

एक अच्छा समाधान है, दुर्भाग्यवश यह केवल 'ActivityUnitTestCase' के साथ काम करता है, लेकिन कार्यात्मक परीक्षण मामलों के साथ नहीं। –

+0

हाँ, मैं सहमत हूं। मैंने यह भी पाया कि कई इरादों को पकड़ना भी संभव नहीं है, उदाहरण के लिए, मेरी गतिविधि कुछ स्टार्टअप स्थिति पर एक इंटेंट सेवा पर एक इरादा भेज सकती है, फिर उपयोगकर्ता एक बटन दबाते समय एक और लॉन्च कर सकता है। सभी को पकड़ना संभव नहीं है। –

1

वैकल्पिक रूप से, आप फिर से कारक हो सकता है आपके कोड आदेश "क्लीन" इकाई परीक्षण (मैं एक इकाई परीक्षण परीक्षण के अंतर्गत वर्ग को छोड़कर बाहर मज़ाक उड़ाया सब कुछ है इसका मतलब यह) करने के लिए। असल में, मेरे पास एक परिस्थिति है, जहां मुझे java.lang.RuntimeException: Stub! मिलता है क्योंकि जिस कोड को मैं इकाई परीक्षण करना चाहता हूं वह नए इरादे बनाता है जिसमें मैंने इंजेक्शन दिया है।

मैं इरादों के लिए अपना कारखाना बनाने पर विचार करता हूं। तब मैं अपने वर्ग-अंडर-परीक्षण करने के लिए एक कारखाने बाहर मज़ाक उड़ाया इंजेक्षन सकता है:

public class MyClassToBeTested { 
    public MyClassToBeTested(IntentFactory intentFactory) { 
     //assign intentFactory to field 
    } 
    .... 
    public void myMethodToTestUsingIntents() { 
     Intent i = intentFactory.create(); 
     i.setAction(AppConstants.INTENT_ACTION_PASSCODE_INPUT); 
     //when doing unit test, inject a mocked version of the 
     //IntentFactory and do the necessary verification afterwards. 
     .... 
    } 
} 

मेरे स्थिति तुम्हारा के रूप में ही नहीं है, लेकिन मेरा मानना ​​है कि आप इसे साथ ही हल करने के लिए एक कारखाने में पैटर्न लागू हो सकते हैं। मैं सच्चे यूनिट परीक्षणों का समर्थन करने के लिए कोड लिखना पसंद करता हूं, लेकिन यह स्वीकार करना होगा कि आपका समाधान काफी चालाक है।

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

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