Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject service with Dagger and Robolectric

I'm trying to inject the service TelephonyManager with Dagger. I'm following this sample. I extended the Application class to create the graph and defined an ApplicationModule where ServiceModule is included and other modules will be included in the future.

Edit:

Now the system service is injected on an Activity without any problems. I was missing FinderApplication.inject(this) inside the Activity. It has an injection but still doesn't inject under testing with Robolectric. I added the test case at the bottom of this post:

Edit-2: ApplicationModule deleted and created BaseActivity with:

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

on onCreate method. The error I'm getting is:

Caused by: java.lang.NoSuchMethodException: ServiceModule.()

But if I define an empty constructor I get a null pointer when the injected class is needed.

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;
        }
    }
}
like image 313
Axxiss Avatar asked Mar 06 '13 20:03

Axxiss


1 Answers

As @AndyDennie said on his comment I was doing no injection in the test class. Injecting the activity under test instead of creating it on setUp() solved the problem.

My current test case (relevant code) looks like this:

@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;
        }
    }
}
like image 54
Axxiss Avatar answered Nov 02 '22 17:11

Axxiss