2014-10-29 59 views
2

是否可以通過匕首將不同的對象注入到android.app.IntentService中,具體取決於它是測試還是生產?Dagger在prod&test中注入IntentService的不同依賴

這主要是將WebRequest類注入到服務中的代碼(簡化)。

public class SomeService extends android.app.IntentService { 

    @Inject 
    WebReqeust mWebRequest; 

    public SomeService(String name) { 
     super(name); 
     MainApplication.getInstance().inject(this); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     String json = mWebRequest.getHttpString(url); 
     JSONObject o = new JSONObject(json); 
     DBHelper.insert(o); 
    } 
} 

@Module(injects = { SomeService.class }) 
    public class WebRequestModule { 

    @Provides 
    WebRequest provideWebRequest() { 
     return new WebRequest(); 
    } 
} 

public class Modules { 

    public static Object[] list() { 
     return new Object[] { 
      new WebRequestModule() 
     }; 
    } 
} 

public class MainApplication extends Application { 

    private ObjectGraph mOjectGraph; 
    private static MainApplication sInstance; 

    @Override 
    public void onCreate() { 
     sInstance = this; 
     mOjectGraph = ObjectGraph.create(Modules.list()); 
    } 

    public void inject(Object dependent) { 
     mOjectGraph.inject(dependent); 
    } 

    public void addToGraph(Object module) { 
     mOjectGraph.plus(module); 
    } 
} 

我想寫一個模擬http響應的測試。 我已經開始與一個新的模塊

@Module(
     injects = SomeService.class, 
     overrides = true 
) 
final class MockTestModule { 
    @Provides 
    WebRequest provideWebRequest() { 
     WebRequest webRequest = mock(WebRequest.class); 
      when(webRequest.getJSONObjectResponse(contains("/register/"))).thenReturn(
        new JSONObject(FileHelper.loadJSONFromAssets(this.getClass(),  
         "mock_register.json"))); 
      when(webRequest.getJSONObjectResponse(contains("/register_validate/"))).thenReturn(
        new JSONObject(FileHelper.loadJSONFromAssets(this.getClass(), 
         "mock_register_validate.json"))); 
     return webRequest; 
    } 
} 

而且在測試中我嘗試以下

public class RegisterTest extends AndroidTestCase { 

    protected void setUp() throws Exception { 
     MainApplication.getInstance().addToGraph(new MockTestModule()); 
     super.setUp(); 
    } 

    public void test_theActuallTest() { 
     Registration.registerUser("[email protected]"); // this will start the service 
     wait_hack(); // This makes the test wait for the reposen form the intentservice, works fine 
     DBHelper.isUserRegisterd("[email protected]")); 
    } 

}

執行測試全成(記住,代碼simplyfied和可能沒有編譯,只是應該代表這個想法)。 但是,它仍然使用「真正的」WebRequest Impl。而不是Mocked。我在日誌,代理服務器和服務器上看到它...

我用RoboGuice以非常類似的方式完成了這項工作,並且它工作正常。但不知何故,我不能用匕首完成這件事。 (我目前正在評估DI框架,這是一個「必須有」)

回答

0

plus方法實際返回新圖。它不覆蓋原始圖形。據說完成你想要的東西,你可以簡單地做到這一點。

public class MainApplication extends Application { 

    ... 

    // Mostly used for testing 
    public void addToGraph(Object module) { 
     mObjectGraph = mOjectGraph.plus(module); 
    } 
} 

這需要原始圖,並用新的模塊就加,然後簡單地分配新的圖形向您mObjectGraph參考。

+0

你對「返回新圖」進行了調整,但並未解決問題。測試仍在使用WebRequest的「生產」實現。 – Christoph 2014-10-30 09:34:20

+0

我假設有別的東西沒有正確連線,但是我看不出你的代碼有什麼問題。我個人使用這種方法與ServiceTestCase和覆蓋我的圖與MockModule和一切工作很好。 – 2014-10-30 14:51:19

+0

我會在接下來的幾天對DI進行更多的研究。一旦我發現什麼是錯的,我會回到這個話題 – Christoph 2014-10-30 14:55:36