Android 用匕首和机器人注入服务
我正试图用Dagger注入服务Android 用匕首和机器人注入服务,android,dependency-injection,robolectric,dagger,Android,Dependency Injection,Robolectric,Dagger,我正试图用Dagger注入服务TelephonyManager。我正在关注这个。我扩展了Application类来创建图形,并定义了一个ApplicationModule,其中包括ServiceModule,将来还将包括其他模块 编辑: 现在,系统服务被注入到活动中,没有任何问题。我缺少查找应用程序。在活动中插入(此)。它有一个注入,但在使用Robolectric进行测试时仍然没有注入。我在本文底部添加了测试用例: 编辑-2: ApplicationModule删除并创建BaseActivity
TelephonyManager
。我正在关注这个。我扩展了Application
类来创建图形,并定义了一个ApplicationModule
,其中包括ServiceModule
,将来还将包括其他模块
编辑:
现在,系统服务被注入到活动中,没有任何问题。我缺少查找应用程序。在活动中插入(此)
。它有一个注入,但在使用Robolectric
进行测试时仍然没有注入。我在本文底部添加了测试用例:
编辑-2:
ApplicationModule
删除并创建BaseActivity
:
((FinderApplication) getApplication()).getGraph().inject(this);
在onCreate
方法上。我得到的错误是:
原因:java.lang.NoSuchMethodException:ServiceModule。()
但是如果我定义一个空构造函数,当需要注入类时,我会得到一个空指针
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;
}
}
@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);
}
}
@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;
}
}
}
ServiceModule.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;
}
}
@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);
}
}
@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;
}
}
}
SimCardActivityTest.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;
}
}
@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);
}
}
@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;
}
}
}
正如@AndyDennie在他的评论中所说,我在测试课上没有做任何注入。注入被测活动而不是在setUp()上创建它解决了问题
我当前的测试用例(相关代码)如下所示:
@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;
}
}
}
我认为@Module注释中的includes标志不会为其他模块提供成员。“包含”用于使用另一个模块来确保满足每个入口点中的所有可注入成员,以便该模块创建一个完整的对象图。因为在应用程序正常运行时正在注入。您可能正在将测试用例注入到对象图而不是活动中?这并不能解释您看到的错误,但我认为在您的安装方法中创建的对象图实际上没有用于任何用途。您可以使用它来调用inject(this),但SimCardActivityTest没有依赖项,因此您没有在那里注入任何内容。我认为您需要在FinderApplication上使用setObjectGraph方法,然后您需要从安装程序中调用它。@AndyDennie您是对的,我认为它们是两个完全不同的图。我需要做的是在SimCardActivity中注入一个模拟对象。次要注释:我相信如果为TelephonyManager提供@Singleton,则不需要声明一个静态实例(TELEPHONY_MANAGER)并返回它。您可以在提供的方法中直接返回Mockito.mock(TelephonyManager.class),因为它只执行一次。