【问题标题】:RoboGuice unit test injecting app module instead of test moduleRoboGuice 单元测试注入应用程序模块而不是测试模块
【发布时间】:2013-05-06 15:33:16
【问题描述】:

我正在尝试使用 RoboGuice 2.0 为 Android 服务编写 JUnit 测试。我有一个测试模块,它将注入的依赖项绑定到 Mockito 模拟对象。但是,当我运行测试时,我的应用程序模块中的真正实现会被注入。以下是一些相关代码:

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 来支持模拟类的字节码生成。另外,我没有使用 Robolectric,而是在设备或模拟器中运行这些测试。

当我运行此测试时,我收到错误 Wanted but not invoked: fooManager.addListener(isA(com.example.IFooListener))。在使用调试器逐步完成之后,我发现 RoboGuice 是从 MainModule 而不是 TestModule 注入依赖项,因此测试使用的是 FooManagerImpl 而不是 MockFooManager。我不明白 RoboGuice 是怎么知道测试代码中的 MainModule 的。

以下是我尝试解决的其他一些问题,但没有任何效果:

  • 在roboguice.xml 中指定应用模块,而不是在MainApplication.onCreate 中调用RoboGuice.setBaseApplicationInjector
  • 在调用RoboGuice.setBaseApplicationInjector 时使用Modules.override 而不是直接传递模块列表。

如何让 RoboGuice 在我的单元测试中使用 TestModule 并忽略 MainModule?

【问题讨论】:

    标签: android junit android-service mockito roboguice


    【解决方案1】:

    您似乎错过了在 NotificationServiceTest 中进行注入的调用。这样做如下:

    RoboGuice.getInjector(app).injectMembers(this);
    

    您需要在设置基础注入器之后和运行测试之前的某个时间点添加它。

    【讨论】:

      【解决方案2】:

      使用

      RoboGuice.overrideApplicationInjector(app,RoboGuice.newDefaultRoboModule(app), new TestModule())
      

      而不是

      RoboGuice.setBaseApplicationInjector(app, RoboGuice.DEFAULT_STAGE, new TestModule());
      

      【讨论】:

        猜你喜欢
        • 2017-05-28
        • 1970-01-01
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-16
        • 2014-05-10
        • 1970-01-01
        相关资源
        最近更新 更多