这是我的第二个问题,与Robolectric + Mockito有关。我一直在努力解决这个问题。我想要做的是窥探一个Activity来测试它的onCreate()回调方法。
我不知道如何在其生命周期中驱动间谍活动以调用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
没有被执行。那么,这是正确的方法吗?如何使用Activity
监视Mockito
并在其生命周期中推动它?
答案 0 :(得分:2)
可能有两种解决方案。
一:
在setup()
方法中,替换controller = Robolectric.buildActivity(MainActivity.class).attach();
而不是controller = Robolectric.buildActivity(MainActivity.class);
另一个:
首先,你应该正确监视活动。 请参阅我在another post
中使用robolectric
监视活动的答案
其次,请勿直接针对间谍活动致电onCreate()
,您应致电ActivityController
create()
,在您的情况下,请致电controller.create()
而不是{ {1}}
答案 1 :(得分:0)
使用Robolectric,您必须致电controller.create();
开始活动。之后它应该工作。
答案 2 :(得分:0)
你需要在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();
}
它是一个模拟生命周期,不是吗?
最后希望这有助于你和其他人也需要它。