2013-01-15 21 views
6

Tôi đang cố gắng sử dụng Dagger trong thử nghiệm chức năng Android kế thừa ActivityInstrumentationTestCase2.Dagger có hỗ trợ tiêm phụ thuộc cho các thử nghiệm ActivityInstrumentationTestCase2

đang

Các thiết lập như sau:

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

Phương pháp OnCreate, mà là bắn bằng cách gọi super.getActivity(), không sử dụng các lớp học được cung cấp bởi các TestModule. Nhưng nếu tôi chạy hoạt động của mình theo cách thủ công (ngoài ngữ cảnh thử nghiệm) thì tất cả các lớp thích hợp được cung cấp/tiêm bởi mô-đun không kiểm tra của tôi.

+0

Vì vậy, nó không phải dễ dàng để xem ở đây những gì đang xảy ra, bởi vì chúng ta không thấy những gì bạn đang tiêm vào thử nghiệm, vv Bạn có thể cắt và cung cấp một ví dụ đơn giản về các mô-đun sản xuất và thử nghiệm của bạn, sao chép vấn đề này? –

+0

Có lẽ câu trả lời của tôi trong bài đăng liên quan này sẽ giúp bạn: http://stackoverflow.com/questions/15630589/android-functional-testing-with-dagger?rq=1 – IIIRepublica

Trả lời

3

Tôi tìm thấy một cách để sử dụng Dagger với ActivityInstrumentationTestCase2 bởi lười biếng tạo Graph Object. Những gì tôi làm là chờ để tạo đồ thị đối tượng cho đến khi lần đầu tiên một lớp muốn được tiêm, miễn là bạn thêm mô-đun trước khi gọi getActivity() (bắt đầu vòng đời hoạt động cho hoạt động đang thử nghiệm) và sử dụng overrides = true trong mô-đun thử nghiệm, điều này sẽ hoạt động. Dưới đây là các lớp và đoạn mã có liên quan:

GraphHolder, như tên ngụ ý, giữ đối tượng ObjectGraph cho chúng tôi. Chúng tôi sẽ thực hiện tất cả các cuộc gọi đến lớp này thay vì trực tiếp đến 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; 
    } 
} 

Chúng tôi sẽ thêm các module của chúng tôi trong lớp Application:

public class MyApplication extends Application { 

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

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

Bên trong lớp chúng tôi muốn tiêm, chúng tôi sẽ chỉ cần gọi GraphHolder.getInstance().inject(this) hơn ObjectGraph.inject(this)

Trong module thử nghiệm của chúng tôi , chúng tôi sẽ cung cấp các đối tượng mà chúng tôi muốn ghi đè để thử nghiệm và thêm overrides = true vào chú thích @Module. Điều này cho đồ thị đối tượng thích các nhà cung cấp mô-đun này hơn những người khác nếu có xung đột.

Sau đó, trong các thử nghiệm của chúng tôi:

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

Mã này đang cố gắng tiêm phụ thuộc tạo ra bởi TestModule vào TestCase của bạn thay vì Hoạt động thử nghiệm. Những gì bạn sẽ phải làm ở đây là

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

+3

bạn không thể đưa vào Hoạt động từ ActivityInstrumentationTestCase2 mặc dù bởi vì bạn phải gọi getActivity() để có được một tham chiếu đến hoạt động, và điều đó sẽ tạo ra nó (gọi onCreate tự động). Vì vậy, nếu bạn thực hiện tiêm trong phương thức onCreate thì sẽ quá muộn để tiêm phụ thuộc nếu bạn cố gắng thiết lập điều này từ ActivityInstrumentationTestCase2. IMO đây là một lỗ hổng lớn trong ActivityInstrumentationTestCase2. Thay vào đó bạn có thể sử dụng ActivityUnitTestCase. –