2013-01-15 3 views
6

ActivityInstrumentationTestCase2를 상속 한 Android 기능 테스트에서 Dagger을 사용하려고합니다.대거는 ActivityInstrumentationTestCase2 테스트에 대한 의존성 주입을 지원합니까?

셋업 코드는 다음과 같습니다

@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()를 호출하여 해고 된 한 OnCreate 방법은 TestModule에서 제공하는 클래스를 사용하지 않습니다. 그러나 테스트 컨텍스트 외부에서 수동으로 활동을 실행하면 모든 적절한 클래스가 비 테스트 모듈에 의해 제공/주입됩니다.

+0

그래서 당신은 트림 및 제공 할 수 있습니다 등, 우리는 당신이 시험에 주입하는지 볼 수 없기 때문에, 여기에 무슨 일이 일어나고 있는지 볼 쉬운 일이 아닙니다 이 문제를 재현하는 생산 및 테스트 모듈의 간단한 예? –

+0

아마이 관련 게시물에 내 대답은 당신을 도와줍니다 : http://stackoverflow.com/questions/15630589/android-functional-testing-with-dagger?rq=1 당신이에서 활동에 주입 할 수 – IIIRepublica

답변

3

입니다. 내가하는 일은 클래스가 주입되기를 원하는 순간까지 Object Graph를 만들기를 기다리는 것입니다. 따라서 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 
     }; 
    } 
} 

, 우리는 단순히 우리의 테스트 모듈에서 ObjectGraph.inject(this)

보다는 GraphHolder.getInstance().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에 의해 만들어진 의존성 주입을 시도하고 있습니다. 당신이 여기에서해야 할 것입니다 것은 내가 게으르게 개체 그래프를 작성하여 ActivityInstrumentationTestCase2와 단검을 사용하는 방법을 발견

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

+3

을 ActivityInstrumentationTestCase2하지만 활동에 대한 참조를 얻으려면 getActivity()를 호출해야하고, 자동으로 onCreate를 호출해야합니다. 따라서 onCreate 메서드에서 주입을 수행하는 경우 ActivityInstrumentationTestCase2에서이 메서드를 설정하려고하면 종속성을 주입하기에는 너무 늦습니다. IMO 이것은 ActivityInstrumentationTestCase2의 큰 결함입니다. 대신 ActivityUnitTestCase를 사용할 수 있습니다. –