【问题标题】:Robolectric 3.8 with MVP and mocking setupActivity()带有 MVP 和模拟 setupActivity() 的 Robolectric 3.8
【发布时间】:2018-05-07 10:01:53
【问题描述】:

我使用 Android MVP 架构,我想测试我的视图。我的项目中有以下代码:

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {


    @Test
    public void testDisplay() throws Exception {
        MainActivity activity = Robolectric.setupActivity(MainActivity.class);

        final Menu menu = Shadows.shadowOf(activity).getOptionsMenu();

        assertEquals("Log", menu.findItem(R.id.menu_login).getTitle().toString());
    }

}

但是,对于某些第 3 方库,我得到 ExceptionInIntializationError 将其抛出到由 Robolectric 调用的 Activity 的 onResume() 步骤中。

此外,在 Activity 的 onResume() 中,Presenter 的方法被调用,它发出网络请求

我的问题是:

  1. 如何模拟第 3 方初始化步骤?我读到了Shadows,但我不知道如何在这个特定场景中使用它们。我应该在setupActivity(...) 通话期间模拟一些东西。
  2. 如何模拟网络调用?在我的 MVP 代码中,演示者是在 onCreate() 方法中创建的。我应该切换到直接依赖注入模式并重建架构吗?但这种方法会与 Robolectric.setupActivity(MainActivity.class); 冲突,因为我需要某种 hook 在 Robolectric 调用期间在 onCreate() 或 onResume() 中注入内容。

【问题讨论】:

    标签: android tdd mvp robolectric android-mvp


    【解决方案1】:

    好的,我想出了以下解决方案。奇怪的是,我从未在他们的页面或文章中看到过类似的例子。我使用 MockitoRobolectric

    首先,我在 Activity(MVP 的视图)中添加了 setPresenter 方法,以将自定义模拟 Presenter 插入到视图中

       @VisibleForTesting
        public void setPresenter(P presenter) {
            this.presenter = presenter;
        }
    

    在我的代码中,Presenter 是 during onCreate() 方法创建的,所以我添加了 null-check 以便在 before 注入 Presenter onCreate():

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        if (presenter == null)
            presenter = providePresenter(App.appComponentFrom(this));
        presenter.create();
    }
    

    在 Robolectric 框架中,我发现 buildActivity() 方法只是调用 Activity 的构造函数(没有生命周期方法!)。

    然后在这个电话之后,我注入了我的模拟演示者。

    最后一步是调用activityController.setup().get(),因为它与setupActivity() 执行相同的工作,即调用生命周期方法:create(), resume()

    @RunWith(RobolectricTestRunner.class)
    @Config(constants = BuildConfig.class, sdk = 21)
    public class MainActivityTest {
    
        @Mock
        CheckoutContract.Presenter presenter;
    
        private ShadowActivity mainActivity;
    
        @Before
        public void setup() {
            MockitoAnnotations.initMocks(this);
    
            ActivityController<MainActivity> activityController = Robolectric.buildActivity(MainActivity.class);
            activityController.get().setPresenter(presenter);
            mainActivity = Shadows.shadowOf(activityController.setup().get());
        }
    
        @Test
        public void checkText() throws Exception {
    
            assertEquals(RuntimeEnvironment.application.getString(R.string.activityMain_title),
                    ((Toolbar)checkoutActivity.findViewById(R.id.vToolbar)).getTitle());
        }
    
    }
    

    瞧!在我的测试中,我从RuntimeEnvironment 获得了上下文资源,它已经通过了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-20
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      相关资源
      最近更新 更多