2013-01-15 23 views
6

test eder.mu Dagger destek dependancy enjeksiyon ben ActivityInstrumentationTestCase2 devralan bir Android fonksiyonel testte <a href="http://square.github.com/dagger/" rel="noreferrer">Dagger</a> kullanmaya çalışıyorum

Kurulum kodu şuna benzer:

@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(); 
}` 

super.getActivity() arayarak ateşlendiğinde OnCreate yöntemi, TestModule tarafından sağlanan sınıfları kullanmaz. Ancak aktivitemi manuel olarak (test kapsamı dışında) çalıştırırsam, test dışı modülüm tarafından tüm uygun sınıflar sağlanır/enjekte edilir.

+0

yüzden kırpıp sağlayabilir vb, size daha testin enjekte ediyorlar görmüyorum, çünkü burada ne olup bittiğini görmek kolay değil Bu sorunu çoğaltan, üretim ve test modüllerinizin basitleştirilmiş bir örneği? –

+0

Belki bu ilgili yayınında cevabım size yardımcı olur: http://stackoverflow.com/questions/15630589/android-functional-testing-with-dagger?rq=1 Eğer bir Aktivite içine enjekte edemez – IIIRepublica

cevap

3

olduğunu. Ne yapmam sen (test altında etkinlik için etkinlik yaşam döngüsünü başlatır olan) getActivity() çağırmadan önce modülleri eklemek yani sürece, bir sınıf enjekte edilmek istiyor ilk defa dek Nesne Grafiği oluşturmak için bekleyip de overrides = true kullanmak aşağıdadır test modülleri, bu işe yarayacak. İlgili sınıflar ve snippet'ler:

GraphHolder, adından da anlaşılacağı gibi bizim için ObjectGraph nesnesini tutuyor. Tüm bu çağrıları doğrudan ObjectGraph yerine bu sınıfa yapacağız.

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; 
    } 
} 

Biz Application sınıfta bizim modülleri ekleyeceğiz:

biz enjekte etmek istiyoruz sınıflar içinde
public class MyApplication extends Application { 

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

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

, biz sadece test modüllerde ObjectGraph.inject(this)

yerine GraphHolder.getInstance().inject(this) arayacağım biz test için geçersiz kılmak ve @Module ek nota overrides = true eklemek istediğiniz nesneleri vereceğiz. Bu, nesne grafiğinin bir çelişki varsa bu modülün sağlayıcılarını başkaları üzerinde tercih etmesini söyler.

Sonra bizim testlerde:

@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);

Bu kod TestCase yerine test Faaliyet içine TestModule yarattığı bağımlılıkları enjekte etmeye çalışıyor. Burada ne olurdu ben tembel Nesne Grafiği oluşturarak ActivityInstrumentationTestCase2 ile Dagger kullanmak için bir yol bulmuş

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

+3

Ancak, ActivityInstrumentationTestCase2, aktiviteye referans almak için getActivity() öğesini çağırmanız gerektiğinden ve bunu oluşturacaksa (otomatik olarak onCreate çağrılıyor). Eğer onCreate stilini Inject yaparsanız ActivityInstrumentationTestCase2 bu kurmak çalışırsanız Böylece, bağımlılıklar enjekte etmek çok geç olacaktır. IMO bu ActivityInstrumentationTestCase2 içinde büyük bir kusurdur. ActivityUnitTestCase'i kullanabilirsiniz. –