使用Robolectric来测试启动活动的代码

时间:2013-10-18 16:20:57

标签: java android robolectric

我想用Robolectric测试一些代码。基本上我想测试一个按钮点击启动一个活动。

HomeScreenFragment.java:

public class HomeScreenFragment extends Fragment {

    private Button mSignInButton;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState); // call to super class
    }

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup parent,
                             Bundle savedInstanceState){

        // inflate view
        View view = inflater.inflate(R.layout.fragment_home_screen, parent, false);

        // handle sign in button
        mSignInButton = (Button)view.findViewById(R.id.sign_in_button);
        mSignInButton.setOnClickListener(new View.OnClickListener() {
            // anonymous inner class
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getActivity(), SignInActivity.class);// start sign in activity with intent
                startActivity(intent); // <<== ERROR HERE WHEN RUNNING TEST

            }
        }
    }
}

我的测试看起来像这样: HomeSreenFragmentTest.java:

@RunWith(RobolectricTestRunner.class)
public class HomeScreenFragmentTest {

    private Activity mHomeScreenActivity;
    private Fragment mTestFragment;
    private Button mSignInButton;

    @Before
    public void setup() throws Exception{

        mHomeScreenActivity = Robolectric.buildActivity(HomeScreenActivity.class).create().get(); // start HomeScreenActivity, call through to onCreate()
        mTestFragment = mHomeScreenActivity.getFragmentManager().findFragmentById(R.id.home_screen_fragment_container);// get HomeScreenFragment

        // run onCreateView
        View testView = mTestFragment.onCreateView(LayoutInflater.from(mHomeScreenActivity),
                (ViewGroup) mHomeScreenActivity.findViewById(R.id.home_screen_fragment_container),
                null);

        // get button view
        mSignInButton = (Button)testView.findViewById(R.id.sign_in_button);

    }

    // clicking sign in button should launch SignInActivity
    @Test
    public void testSignInButton2() throws Exception{
        mSignInButton.performClick(); <<=== ERROR STARTS HERE
        ShadowActivity shadowActivity = Robolectric.shadowOf(mHomeScreenActivity); // create shadow activity
        Intent startedIntent = shadowActivity.getNextStartedActivity();            // get intent of next activity on stack
        ShadowIntent shadowIntent = Robolectric.shadowOf(startedIntent);            // create shadow intent which starts next activity
        assertEquals(SignInActivity.class.getName(), shadowIntent.getComponent().getClassName()); // compare shadow intent w/ desired next activity
    }

我遇到的问题是测试。代码本身在仿真器/设备上工作正常。问题是,当Robolectric运行performClick()方法,然后转到onClick()然后转到startActivity(intent)它失败。

堆栈跟踪:

java.lang.NullPointerException: null
    at android.app.Activity.startActivityFromFragment(Activity.java:3850)
    at android.app.Activity.startActivityFromFragment(Activity.java:3825)
    at android.app.Fragment.startActivity(Fragment.java:996)
    at android.app.Fragment.startActivity(Fragment.java:975)
    at com.********.android.***project*****.controller.HomeScreenFragment$1.onClick(HomeScreenFragment.java:42)
    at android.view.View.performClick(View.java:4084)
    at com.*********.android.***project***.HomeScreenFragmentTest.testSignInButton2(HomeScreenFragmentTest.java:83)

我知道如何使用Robolectric.buildActivity()方法使用Robolectric启动活动。但这适用于我需要在测试中的活动。为什么Robolectric无法在代码中运行startActivity()方法?有没有更好的方法来测试这个?

1 个答案:

答案 0 :(得分:10)

您还应该在.start().resume()上致电ActivityController,而不仅仅是.create()这也会导致片段被创建。

如果您执行上述操作,则无需亲自致电onCreateView。您只需使用mHomeScreenActivity.findViewById(R.id.sign_in_button);

从活动中获取按钮即可

一般情况下,我怀疑您的代码失败,因为片段还没有完全启动,因为您没有调用start()resume()