如何为Android体系结构组件生命周期事件添加单元测试?

问题描述 投票:4回答:4

我试图为支持架构组件生命周期事件的功能添加单元测试。为了支持生命周期事件,我为函数添加了@OnLifecycleEvent批注,该事件发生时我想做一些事情。

一切都按预期工作,但我想为该功能创建一个单元测试,以在发生预期事件时检查我的功能是否运行。

 public class CarServiceProvider implements LifecycleObserver {

    public void bindToLifeCycle(LifecycleOwner lifecycleOwner) {
        lifecycleOwner.getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onClear() {
       Log.i("CarServiceProvider", "onClear called");
    }
 }

我试图模拟LifecycleOwner并创建新的LifecycleRegistery来更改生命周期观察者的状态,但我没有这样做。

如何更改状态更改后调用的onClear()函数?

android android-testing android-architecture-components android-architecture-lifecycle
4个回答
2
投票

尽管我不是一个忠实的粉丝,但我还是会选择Robolectric来利用ActivityController来实现这一目标。

鉴于Observer pattern的“可观测值”应用于Android Lifecycle工作流是“活动”,“片段”……应用程序上下文是必须的,我们需要以某种方式将其引入我们的测试场景。

我通过这样做达到了预期的结果

build.gradle

testCompile "org.robolectric:robolectric:3.5.1"

CarServiceProviderTest.java

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class CarServiceProviderTest {

    @Test
    public void shouldFireOnClear(){

        //Grab the Activity controller
        ActivityController controller = Robolectric.buildActivity(JustTestActivity.class).create().start();
        AppCompatActivity activity = (AppCompatActivity) controller.get();

        //Instanciate our Observer
        CarServiceProvider carServiceProvider = new CarServiceProvider();
        carServiceProvider.bindToLifeCycle(activity);

        //Fire the expected event
        controller.stop();

        //Assert
        Assert.assertTrue(carServiceProvider.wasFired);
    }
}

CarServiceProvider.java

public class CarServiceProvider implements LifecycleObserver {

    public boolean wasFired;

    public void bindToLifeCycle(LifecycleOwner lifecycleOwner) {
        lifecycleOwner.getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onClear() {
        wasFired = true;
    }
}

4
投票

您应该可以使用LifecycleRegistry

您的测试将执行以下操作:

@Test
public void testSomething() {
  LifecycleRegistry lifecycle = new LifecycleRegistry(mock(LifecycleOwner.class));

  // Instantiate your class to test
  CarServiceProvider carServiceProvider = new CarServiceProvider();
  carServiceProvider.bindToLifeCycle(lifecycle);

  // Set lifecycle state
  lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)

  // Verify that the ON_STOP event was handled, with an assert or similar check
  ...
}

如果您正在测试Lifecycle.Event.ON_DESTROY,那么您可能需要在此之前调用handleLifecycleEvent(Lifecycle.Event.ON_CREATE)


0
投票

[如果您要使用真实的单元测试(而不是AndroidTest)进行测试,最好的选择是使用Robolectric,它模拟Android框架,而Robolectric 4.0即将问世。但是,您正在尝试测试与Android Framework的实际交互,因此这是一个更适合真正的集成测试套件和AndroidTest的任务。您可以对其进行单元测试,但是最确定的测试方法是在设备上实际调用生命周期事件(Espresso会执行的操作)并验证它是否被调用。


0
投票

只要您正确地模拟了生命周期所有者,就可以在不使用Roboletric的情况下使用单元测试进行测试。

val lifecycleOwner: LifecycleOwner = Mockito.mock(LifecycleOwner::class.java)
val lifecycle = LifecycleRegistry(Mockito.mock(LifecycleOwner::class.java))
lifecycle.markState(Lifecycle.State.RESUMED)
Mockito.`when`(lifecycleOwner.lifecycle).thenReturn(lifecycle)

[观察变量时使用此lifecycleOwner,可以使用Mockito.verify来查看是否已调用回调

© www.soinside.com 2019 - 2024. All rights reserved.