2013-01-15 15 views
6

के लिए निर्भरता इंजेक्शन का समर्थन करता है मैं एंड्रॉइड कार्यात्मक परीक्षण में Dagger का उपयोग करने की कोशिश कर रहा हूं जो ActivityInstrumentationTestCase2 को प्राप्त करता है।क्या Dagger गतिविधिInstrumentationTestCase2 परीक्षण

सेटअप कोड इस तरह दिखता है:

@Override 
protected void setUp() { 
    // TODO Auto-generated method stub 
    try { 
     super.setUp(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    ObjectGraph.create(new TestModule()).inject(this); 
    this.activity = super.getActivity(); 
}` 

OnCreate विधि है, जो super.getActivity() फोन करके निकाल दिया जाता है, TestModule द्वारा प्रदान की कक्षाओं का उपयोग नहीं करता। लेकिन अगर मैं अपनी गतिविधि को मैन्युअल रूप से चलाता हूं (परीक्षण संदर्भ के बाहर) तो सभी उपयुक्त वर्ग मेरे गैर-परीक्षण मॉड्यूल द्वारा प्रदान/इंजेक्शन दिए जाते हैं।

+0

तो यह आसान नहीं यहाँ क्या चल रहा है देखने के लिए, क्योंकि हम नहीं देखते हैं क्या आप परीक्षण में इंजेक्शन लगाने रहे हैं, आदि आप ट्रिम और प्रदान कर सकते हैं आपके उत्पादन और परीक्षण मॉड्यूल का एक सरल उदाहरण, जो इस मुद्दे को दोहराता है? –

+0

हो सकता है कि यह संबंधित पोस्ट में मेरा उत्तर में सहायक है: http://stackoverflow.com/questions/15630589/android-functional-testing-with-dagger?rq=1 – IIIRepublica

उत्तर

3

मैं lazily वस्तु ग्राफ़ बनाने के द्वारा ActivityInstrumentationTestCase2 साथ डैगर उपयोग करने के लिए एक रास्ता मिल गया है। मैं जो करता हूं वह ऑब्जेक्ट ग्राफ़ बनाने के लिए प्रतीक्षा करता है जब तक कि कक्षा पहली बार इंजेक्शन नहीं लेती, तब तक जब तक आप getActivity() (जो परीक्षण के तहत गतिविधि के लिए गतिविधि जीवन चक्र शुरू करता है) को कॉल करने से पहले अपने मॉड्यूल जोड़ते हैं और overrides = true का उपयोग करें परीक्षण मॉड्यूल, यह काम करेगा। यहां प्रासंगिक कक्षाएं और स्निपेट हैं:

GraphHolder, जैसा कि नाम का तात्पर्य है, हमारे लिए ObjectGraph ऑब्जेक्ट रखता है। हम ObjectGraph पर सीधे इस वर्ग में सभी कॉल करेंगे।

public class GraphHolder { 

    private static GraphHolder sInstance; 

    private Object[] mModules; 
    private ObjectGraph mGraph; 

    private GraphHolder() { 
    } 

    public static GraphHolder getInstance() { 
     if (sInstance == null) { 
      sInstance = new GraphHolder(); 
     } 

     return sInstance; 
    } 

    public void inject(Object object) { 
     if (mGraph == null) { 
      create(); 
     } 

     mGraph.inject(object); 
    } 

    public <T> T get(Class<T> type) { 
     if (mGraph == null) { 
      create(); 
     } 

     return mGraph.get(type); 
    } 

    public void addModules(Object... modules) { 
     if (mGraph != null) { 
      mGraph.plus(modules); 
     } else { 
      if (mModules == null) { 
       mModules = modules; 
      } else { 
       mModules = concatenate(mModules, modules); 
      } 
     } 
    } 

    private void create() { 
     mGraph = ObjectGraph.create(mModules); 
     mModules = null; 
    } 

    private Object[] concatenate(Object[] a, Object[] b) { 
     int aLength = a.length; 
     int bLength = b.length; 

     Object[] c = new Object[aLength + bLength]; 
     System.arraycopy(a, 0, c, 0, aLength); 
     System.arraycopy(b, 0, c, aLength, bLength); 

     return c; 
    } 
} 

हम Application कक्षा में हमारे मॉड्यूल जोड़ देंगे:

public class MyApplication extends Application { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     GraphHolder.getInstance().addModules(getModules()); 
    } 

    Object[] getModules() { 
     return new Object[]{ 
       // your modules here 
     }; 
    } 
} 

कक्षाओं हम इंजेक्षन करना चाहते हैं अंदर, हम बस GraphHolder.getInstance().inject(this) बजाय ObjectGraph.inject(this)

हमारे परीक्षण मॉड्यूल में फोन करता हूँ , हम उन वस्तुओं को प्रदान करेंगे जिन्हें हम परीक्षण के लिए ओवरराइड करना चाहते हैं और overrides = true@Module एनोटेशन में जोड़ें। यह ऑब्जेक्ट ग्राफ़ को इस मॉड्यूल के प्रदाताओं को किसी अन्य संघर्ष पर प्राथमिकता देने के लिए कहता है।

फिर, हमारे परीक्षणों में:

@Inject Foo mFoo; 

@Override 
public void setUp() { 
    super.setUp(); 
    GraphHolder.getInstance().addModules(new TestFooModule()); 
    GraphHolder.getInstance().inject(this); // This is when the object graph will be created 
} 
1

ObjectGraph.create(new TestModule()).inject(this);

यह कोड आपके बजाय testcase परीक्षण किया गतिविधि में TestModule द्वारा बनाई निर्भरता इंजेक्षन करने की कोशिश कर रहा है। क्या तुम यहाँ कर दिया था

ObjectGraph.create(new TestModule()).inject(this.activity);

+3

आप से एक गतिविधि में इंजेक्षन नहीं कर सकते ActivityInstrumentationTestCase2 यद्यपि आपको गतिविधि के संदर्भ प्राप्त करने के लिए getActivity() को कॉल करना है, और यह इसे बनाएगा (स्वचालित रूप से क्रिएट करना)। इस प्रकार, यदि आप ऑनक्रेट विधि में अपना इंजेक्ट करते हैं तो आप निर्भरता इंजेक्ट करने में बहुत देर हो जाएंगे यदि आप इसे ActivityInstrumentationTestCase2 से सेट अप करने का प्रयास करते हैं। आईएमओ गतिविधिInstrumentationTestCase2 में यह एक बड़ी खामियां है। आप इसके बजाय ActivityUnitTestCase का उपयोग कर सकते हैं। –