我有以下活动:
package codeguru.startactivityforresult; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class ChildActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.child); this.resultButton = (Button) this.findViewById(R.id.result_button); this.resultButton.setOnClickListener(onResult); } private View.OnClickListener onResult = new View.OnClickListener() { @Override public void onClick(View view) { Intent result = new Intent(); result.putExtra(ChildActivity.this.getString(R.string.result), ChildActivity.this.getResources().getInteger(R.integer.result)); ChildActivity.this.setResult(RESULT_OK, result); ChildActivity.this.finish(); } }; private Button resultButton = null; }
并进行以下JUnit测试:
package codeguru.startactivityforresult; import android.app.Activity; import android.test.ActivityInstrumentationTestCase2; import android.test.UiThreadTest; import android.widget.Button; import junit.framework.Assert; public class ChildActivityTest extends ActivityInstrumentationTestCase2<ChildActivity> { public ChildActivityTest() { super(ChildActivity.class); } @Override public void setUp() throws Exception { super.setUp(); this.setActivityInitialTouchMode(false); this.activity = this.getActivity(); this.resultButton = (Button) this.activity.findViewById(R.id.result_button); } @Override public void tearDown() throws Exception { super.tearDown(); } @UiThreadTest public void testResultButtonOnClick() { Assert.assertTrue(this.resultButton.performClick()); Assert.fail("How do I check the returned result?"); } private Activity activity; private Button resultButton; }
我如何确保单击按钮设置正确的结果(调用setResult()),该结果将返回到任何以此为起始的活动startActivityForResult()?
setResult()
startActivityForResult()
使用问题中的当前Activity实现,即,通过单击ChildActivity中的按钮设置结果,然后立即销毁该活动,在ChildActivityTest中我们无法做很多测试结果相关的东西。
相关问题测试onActivityResult()的答案显示了如何在MainActivityTest中独立测试startActivityForResult()和/或onActivityResult()。通过独立方式,MainActivityTest不依赖于ChildActivity的交互,检测将捕获ChildActivity的创建并立即将其杀死,然后返回准备好的烘焙模拟ActivityResult,从而对MainActivity进行单元测试。
如果您不希望检测中断并返回模拟的ActivityResult,则可以让ChildActivity继续进行,然后在ChildActivity中模拟交互,然后将实际的ActivityResult返回给MainActivity。说如果您要MainActivity启动ChildActivity作为结果,然后更新TextView,以测试整个端到端的交互/合作,请参见下面的示例代码:
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { ... ... public void testStartActivityForResult() { MainActivity mainActivity = getActivity(); assertNotNull(activity); // Check initial value in TextView: TextView text = (TextView) mainActivity.findViewById(com.example.R.id.textview1); assertEquals(text.getText(), "default vaule"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // Create an ActivityMonitor that monitor ChildActivity, do not interrupt, do not return mock result: Instrumentation.ActivityMonitor activityMonitor = getInstrumentation().addMonitor(ChildActivity.class.getName(), null , false); // Simulate a button click in MainActivity that start ChildActivity for result: final Button button = (Button) mainActivity.findViewById(com.example.R.id.button1); mainActivity.runOnUiThread(new Runnable() { public void run() { button.performClick(); } }); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } getInstrumentation().waitForIdleSync(); ChildActivity childActivity = (ChildActivity) getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 5); // ChildActivity is created and gain focus on screen: assertNotNull(childActivity); // Simulate a button click in ChildActivity that set result and finish ChildActivity: final Button button2 = (Button) childActivity.findViewById(com.example.R.id.button1); childActivity.runOnUiThread(new Runnable() { public void run() { button2.performClick(); } }); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } getInstrumentation().waitForIdleSync(); // TextView in MainActivity should be changed: assertEquals(text.getText(), "default value changed"); } ... ... }
我在这里添加了三个Thread.sleep()调用,以便您有机会在运行JUnit Test时看到单击模拟的按钮。如您在这里看到的那样,一个独立的ChildActivityTest不足以测试整个合作,实际上我们是通过MainActivityTest间接测试ChildActivity.setResult()的,因为我们从一开始就需要模拟整个交互。