【问题标题】:Android functional testing with Dagger使用 Dagger 进行 Android 功能测试
【发布时间】:2013-03-26 06:19:53
【问题描述】:

我正在尝试使用 Mockito 和 Dagger 测试一个 Activity。我已经能够在我的应用程序中向 Activity 注入依赖项,但是在测试 Activity 时,我无法向 Activity 注入模拟。我应该注入 Activity 来测试还是让 getActivity() 创建它?

public class MainActivityTest extends
    ActivityInstrumentationTestCase2<MainActivity> {

@Inject Engine engineMock;
private MainActivity mActivity;
private Button mLogoutBtn;


public MainActivityTest() {
    super(MainActivity.class);
}

@Override
protected void setUp() throws Exception {
    super.setUp();

    // Inject engineMock to test
    ObjectGraph.create(new TestModule()).inject(this);
}

@Override
protected void tearDown() {
    if (mActivity != null)
        mActivity.finish();
}

 @Module(
 includes = MainModule.class,
 entryPoints = MainActivityTest.class,
 overrides = true
 )

static class TestModule {
    @Provides
    @Singleton
    Engine provideEngine() {
        return mock(Engine.class);
    }
}

@UiThreadTest
public void testLogoutButton() {

    when(engineMock.isLoggedIn()).thenReturn(true);

    mActivity = getActivity();
    mLogoutBtn = (Button) mActivity.findViewById(R.id.logoutButton);

    // how to inject engineMock to Activity under test?
    ObjectGraph.create(new TestModule()).inject(this.mActivity);

    assertTrue(mLogoutBtn.isEnabled() == true);
}
}

【问题讨论】:

    标签: android dependency-injection mockito functional-testing dagger


    【解决方案1】:

    我使用 Mockito 和 Dagger 进行功能测试。 关键概念是您的测试类继承自 ActivityUnitTestCase,而不是 ActivityInstrumentationTestCase2;后一个超类调用 Activity 的 onStart() 生命周期方法阻止您注入测试加倍依赖项,但使用第一个超类,您可以更细粒度地处理生命周期。

    您可以在以下位置查看我使用 dagger-1.0.0 和 mockito 测试活动和片段的工作示例:

    https://github.com/IIIRepublica/android-civicrm-test

    被测项目在:

    https://github.com/IIIRepublica/android-civicrm

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      我做了更多的实验,发现 Dagger 在注入测试时无法正确创建活动。在新版本的测试中,testDoSomethingCalledOnEngine 通过了,但没有在 MainActivity 上调用 onCreate。第二个测试,testDoSomethingUI 失败,实际上有两个 MainActivity 实例,onCreate 被调用到另一个实例(由我的 ActivityInstrumentationTestCase2 创建)而不是另一个。也许 Square 的开发人员只想用 Robolectric 测试 Activites 而不是 Android 仪器测试?

      public class MainActivityTest extends
          ActivityInstrumentationTestCase2<MainActivity> {
      
      @Inject Engine engineMock;
      @Inject MainActivity mActivity;
      
      public MainActivityTest() {
          super(MainActivity.class);
      }
      
      @Override
      protected void setUp() throws Exception {
          super.setUp();
      
          // Inject engineMock to test & Activity under test
          ObjectGraph.create(new TestModule()).inject(this);
      }
      
      
       @Module(
       includes = MainModule.class,
       entryPoints = MainActivityTest.class,
       overrides = true
       )
      
      static class TestModule {
          @Provides
          @Singleton
          Engine provideEngine() {
              return mock(Engine.class);
          }
      }
      
      public void testDoSomethingCalledOnEngine() {
          when(engineMock.isLoggedIn()).thenReturn(true);
          mActivity.onSomethingHappened();
          verify(engineMock).doSomething();
      }
      
      @UiThreadTest
      public void testDoSomethingUI() {
          when(engineMock.isLoggedIn()).thenReturn(true);
          mActivity.onSomethingHappened();
          Button btn = (Button) mActivity.findViewById(R.id.logoutButton);
          String btnText = btn.getText().toString(); 
          assertTrue(btnText.equals("Log out"));  
      }
      

      }

      【讨论】:

      • 我们的活动将自己注入到 onCreate 中(在基类中)。我们使用应用程序类的开发版本将仅开发模块添加到对象图中。
      • @JakeWharton 你能指出一个例子,你让 Dagger 在 ui 测试中注入模拟吗?我从您创建的一些插件中知道您使用过 Espresso。您如何为您的 espresso 测试实现测试模拟的示例将非常宝贵!
      【解决方案3】:

      我已将所有内容放在一起并制作了演示应用程序,展示了如何使用 dagger 进行测试:https://github.com/vovkab/dagger-unit-test

      这是我以前的回答,其中包含更多详细信息:
      https://stackoverflow.com/a/24393265/369348

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-11
        • 2014-06-07
        • 2019-07-05
        • 2015-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-08
        相关资源
        最近更新 更多