2013-03-06 15 views
6

Sto provando a iniettare il servizio TelephonyManager con Dagger. Sto seguendo questo sample. Ho esteso la classe Application per creare il grafico e definito un ApplicationModule dove è incluso lo standard ServiceModule e altri moduli verranno inclusi in futuro.Inject service with Dagger and Robolectric

Edit:

Ora il servizio di sistema viene iniettato in un Activity senza problemi. Mi mancava FinderApplication.inject(this) all'interno dello Activity. Ha un'iniezione, ma non viene iniettata sotto test con Robolectric. Ho aggiunto il banco di prova in fondo a questo post:

Edit-2: ApplicationModule cancellato e creato BaseActivity con:

((FinderApplication) getApplication()).getGraph().inject(this); 

su onCreate metodo. L'errore che sto ricevendo è:

causato da: java.lang.NoSuchMethodException:. ServiceModule()

Ma se io definisco uno vuoto, ho un puntatore nullo quando la classe è iniettato necessario.

FinderApplication.java

public class FinderApplication extends Application { 
    private ObjectGraph mObjectGraph; 

    @Override 
    public final void onCreate() { 
     super.onCreate(); 
     mObjectGraph = ObjectGraph.create(new ServiceModule(this)); 
    } 

    public final ObjectGraph getGraph() { 
     return mObjectGraph; 
    } 
} 

ServiceModule.java

@Module(entryPoints = { SimCardActivity.class, SimService.class }) 
public class ServiceModule { 

    private Context mContext; 

    public ServiceModule(Context context) { 
     mContext = context; 
    } 

    @Provides @Singleton 
    TelephonyManager provideTelephonyManager(){ 
     return (TelephonyManager) mContext 
      .getSystemService(Context.TELEPHONY_SERVICE); 
    } 
} 

SimCardActivityTest.java

@RunWith(RobolectricTestRunner.class) 
public class SimCardActivityTest { 

    @Before 
    public void setUp() throws Exception { 
     ObjectGraph.create(new TestModule()).inject(this);; 
    } 

    @Module(
      includes = ServiceModule.class, 
      overrides = true, 
      entryPoints = {SimCardActivityTest.class, SimCardActivity.class} 
    ) 
    static class TestModule{ 
     public static TelephonyManager TELEPHONY_MANAGER = 
      Mockito.mock(TelephonyManager.class); 

     @Provides @Singleton 
     TelephonyManager provideTelephonyManager(){ 
      return TELEPHONY_MANAGER; 
     } 
    } 
} 
+0

non credo che la include bandiera l'annotazione @modulo fornirà ai membri per altri moduli. "include" è per l'utilizzo di un altro modulo per assicurarsi che tutti i membri iniettabili in ogni punto di ingresso siano soddisfatti, in modo che il modulo crei un grafico completo degli oggetti. – SeanPONeil

+0

Sembra che include flag include davvero i moduli specificati. Perché si sta iniettando normalmente quando l'app è in esecuzione. – Axxiss

+1

Stai iniettando il caso di test nel grafico dell'oggetto invece dell'attività, forse? – SeanPONeil

risposta

3

Come @AndyDennie ha detto sul suo commento che stavo facendo nessuna iniezione nella classe di test. L'iniezione dell'attività sotto test invece di crearla su setUp() ha risolto il problema.

Il mio attuale banco di prova (codice rilevante) si presenta così:

@RunWith(RobolectricTestRunner.class) 
public class SimCardActivityTest { 

    @Inject 
    private SimCardActivity mActivity; 

    private TelephonyManager mTelephonyManager; 

    @Before 
    public void setUp() throws Exception { 
     ObjectGraph.create(new ServiceModule(Robolectric.application), 
          new ServiceTestModule()).inject(this); 
    } 

    @Module(
      includes = {ServiceModule.class }, 
      overrides = true, 
      entryPoints = {SimCardActivity.class, SimCardActivityTest.class} 
    ) 
    static class ServiceTestModule { 
     public static TelephonyManager TELEPHONY_MANAGER = 
      Mockito.mock(TelephonyManager.class); 

     @Provides 
     @Singleton 
     TelephonyManager provideTelephonyManager(){ 
      return TELEPHONY_MANAGER; 
     } 
    } 
} 
+0

Commento secondario: credo che se si fornisce TelephonyManager con @Singleton, non è necessario dichiarare un'istanza statica (TELEPHONY_MANAGER) e restituirla. È possibile reindirizzare Mockito.mock (TelephonyManager.class), nel metodo provid, poiché verrà eseguito una sola volta. – GaRRaPeTa