RoboGuice 2.0を使用してAndroidサービス用のJUnitテストを作成しようとしています。私は注入された依存関係をMockitoモックオブジェクトにバインドするテストモジュールを持っています。しかし、テストを実行すると、私のアプリケーションモジュールからの実際の実装が代わりに注入されます。テストモジュールの代わりにRoboGuiceユニットテスト注入モジュール
MainApplication.java:
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
RoboGuice.setBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE,
RoboGuice.newDefaultRoboModule(this), new MainModule());
startService(new Intent(this, NotificationService.class));
}
}
MainModule.java:
public class MainModule extends AbstractModule {
@Override
protected void configure() {
bind(IFooManager.class).to(FooManagerImpl.class).in(Scopes.SINGLETON);
}
}
NotificationService.java:
public class NotificationService extends RoboService {
@Inject
private NotificationManager notificationManager;
@Inject
private SharedPreferences prefs;
@Inject
private IFooManager fooManager;
private IFooListener listener = new FooListener();
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
fooManager.addListener(listener);
}
@Override
public void onDestroy() {
super.onDestroy();
fooManager.removeListener(listener);
}
private class FooListener implements IFooListener {
// Do stuff that fires Notifications
}
}
NotificationServiceTest.java:
ここに関連するコードの一部ですpublic class NotificationServiceTest extends ServiceTestCase<NotificationService> {
@Mock
private MockFooManager fooManager;
@Mock
private MockSharedPreferences prefs;
public NotificationServiceTest() {
super(NotificationService.class);
}
public void testStart() {
startService(null);
verify(fooManager).addListener(isA(IFooListener.class));
}
public void testStop() {
shutdownService();
verify(fooManager).removeListener(isA(IFooListener.class));
}
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
Application app = new MockApplication();
setApplication(app);
RoboGuice.setBaseApplicationInjector(app, RoboGuice.DEFAULT_STAGE, new TestModule());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
RoboGuice.util.reset();
}
private class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(Context.class).toInstance(getContext());
bind(IFooManager.class).toInstance(fooManager);
bind(SharedPreferences.class).toInstance(prefs);
}
}
}
MockFooManagerとMockSharedPreferencesはIFooManagerとSharedPreferencesの抽象実装が空のため、RoboGuice can't inject mocks of interfacesが必要です。私は、Mockitoクラスのバイトコード生成をサポートするためにDexmakerでMockitoを使用しています。また、私はRobolectricを使用していません。デバイスまたはエミュレータでこれらのテストを実行しています。
このテストを実行すると、エラーWanted but not invoked: fooManager.addListener(isA(com.example.IFooListener))
が発生します。これをデバッガでステップ実行した後、私はRoboGuiceがTestModuleではなくMainModuleからの依存関係を注入していることがわかりました。そのため、MockFooManagerの代わりにFooManagerImplを使用しています。私は、RoboGuiceがテストコードのMainModuleについて知っていることさえ理解できません。
roboguice.xml
の代わりRoboGuice.setBaseApplicationInjector
を呼び出すだけではなく渡すときに使用Modules.override
MainApplication.onCreate
- で
RoboGuice.setBaseApplicationInjector
を呼んでアプリモジュールを指定します。ここではは、私はこの問題を解決しようとしましたが、どれも何の効果もなかったいくつかの他のものがありますモジュール一覧を直接。
ユニットテストでRoboGuiceにTestModuleを使用させ、MainModuleを無視させる方法を教えてください。