【问题标题】:Robolectric and Mockito spying Android ActivityRobolectric 和 Mockito 监视 Android 活动
【发布时间】:2015-01-05 20:16:50
【问题描述】:

这是我与 Robolectric + Mockito 相关的第二个问题。我已经为此苦苦挣扎了几天。我要做的是监视一个 Activity 来测试它的 onCreate() 回调方法。

我不知道如何在其生命周期中驱动被监视的 Activity 以便调用 onCreate()。这是我的活动:

public class MainActivity extends FragmentActivity {

    public Session session; // Facebook session

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        session = getActiveSession();
        if (session == null ) {
            // ...
        } else {
            if (sessionClosed()) {
                LoginFragment fragment = new LoginFragment();
                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.container, fragment);
                ft.commit();
            }
        }
    }

    ...

    public Session getActiveSession() {
        return Session.getActiveSession();
    }

    public boolean sessionClosed() {
        return session.isClosed();
    }

}

这是我的测试尝试:

@RunWith(RobolectricTestRunner.class)
public class MainActivityTest {

    private ActivityController<MainActivity> controller;
    private MainActivity activity;
    private MainActivity spy;

    @Before
    public void setup() throws Exception {
        controller = Robolectric.buildActivity(MainActivity.class);
        activity = (MainActivity) controller.get();
    }

    ...

    @Test
    public void testShowLoginWhenSessionClosed() throws Exception {
        Session session = new Session(Robolectric.application);
        spy = Mockito.spy(activity);

        Mockito.doReturn(session).when(spy).getActiveSession();
        Mockito.doReturn(true).when(spy).sessionClosed();

        spy.onCreate(null);

        Mockito.verify(spy).getActiveSession();

        Fragment fragment = 
            spy.getSupportFragmentManager().findFragmentById(R.id.container);
        Assert.assertTrue(fragment instanceof LoginFragment);

    }
}

但是,当测试调用spy.onCreate(null) 时,我得到以下异常:

java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:4492)
at android.view.LayoutInflater.from(LayoutInflater.java:211)
at org.robolectric.shadows.ShadowActivity.getLayoutInflater(ShadowActivity.java:148)
at android.app.Activity.getLayoutInflater(Activity.java)
at org.example.MainActivityTest.testShowLoginWhenSessionClosed(MainActivityTest.java:110)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

当然,如果我不调用它,Verify() 会失败,因为onCreate 没有被执行。那么,这是正确的方法吗?如何使用Mockito 监视Activity 并在其生命周期中驱动它?

【问题讨论】:

  • 您找到解决方案了吗?我也陷入了同样的境地。

标签: java android testing mockito robolectric


【解决方案1】:

可能有两种解决方案。

一个:

setup()方法中,替换controller = Robolectric.buildActivity(MainActivity.class).attach();而不是controller = Robolectric.buildActivity(MainActivity.class);


另一个:

首先,您应该正确地监视活动。 请参阅我在another post 中使用robolectric 监视活动的答案

其次,不要在间谍活动中直接调用onCreate(),你应该调用ActivityControllercreate(),在你的情况下,调用controller.create()而不是spy.onCreate(null);

【讨论】:

    【解决方案2】:

    使用 Robolectric,您必须致电 controller.create(); 才能开始活动。之后它应该工作。

    【讨论】:

      【解决方案3】:

      你只需要在 get() 之前调用 setup():

      controller.setup();
      

      如果不需要控制器实例,我强烈建议您通过以下代码获取 Activity:

      activity = Roblectric.setupActivity(MainActivity.class);
      

      我们可以看到,这些 API 的区别在于 setup() 和 get():

        public static <T extends Activity> ActivityController<T> buildActivity(Class<T> activityClass) {
          return ActivityController.of(shadowsAdapter, activityClass);
        }
      
        public static <T extends Activity> T setupActivity(Class<T> activityClass) {
          return ActivityController.of(shadowsAdapter, activityClass).setup().get();
        }
      

      所以你崩溃的原因是 setup():

        public ActivityController<T> setup() {
          return create().start().postCreate(null).resume().visible();
        }
      

      这是一个模拟生命周期,不是吗?

      最后希望这对你和其他需要它的人有所帮助。

      【讨论】:

      • 但是他需要在调用create()之前监视活动并更改getActiveSession()方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-15
      相关资源
      最近更新 更多