我有以下活动:
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()
启动此活动的任何活动?
答案 0 :(得分:6)
在问题中使用当前的Activity实现,即通过单击ChildActivity中的按钮设置结果然后立即销毁活动,我们在ChildActivityTest中没有太多可以用来测试与结果相关的东西。
相关问题Testing 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(),因为我们需要从一开始就模拟整个交互。
答案 1 :(得分:1)
我建议使用Robotium框架。 Robotium使用Solo类,它有一个非常有用的API。
它允许您查看当前活动的内容。允许您断言活动已经开始等。
http://code.google.com/p/robotium/
执行点击后,您可以执行类似
的操作void assertCurrentActivity(java.lang.String message,java.lang.Class expectedClass,boolean isNewInstance) 这就是我要做的事情。 在代码之后单击按钮
Activity callingActvity = solo.getCurrentActivity();
solo.assertCurrentActivity("ShouldbeCallingActivity","NameOfCallingActivity");
在不知道回调如何工作的情况下,我无法提供完整的解决方案。但假设某些文本显示为RESULT_OK而不是其他一些文本,
你可以做点什么assertTrue(solo.waitForText("Text that is supposed to show for Result OK");
PS:robotium仅适用于同一应用程序中的活动。