10

我有一些我想用 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()在代码中运行该方法?有没有更好的方法来测试这个?

4

1 回答 1

10

您还应该调用.start().resume()您的ActivityController, 不仅.create()这会导致创建片段。

如果您执行上述操作,则无需调用onCreateView自己。您可以使用从活动中获取按钮mHomeScreenActivity.findViewById(R.id.sign_in_button);

一般来说,我怀疑你的代码失败是因为片段还没有完全开始,因为你没有调用start()resume()

于 2013-10-26T10:47:37.083 回答