Android/測試/單元測試/監控超類方法
外觀
一些監控行為很常見:例如,活動可以啟動其他活動,測試這些呼叫涉及記錄測試期間發出的意圖。Robolectric 透過其 ShadowContextWrapper.getNextActivity 提供此行為,但在某些情況下,以下策略可能更有用。
啟動另一個活動的活動。
class MyActivity extends Activity {
...
protected void startSomeActivity() {
startActivity(new Intent("start some activity");
}
...
}
擴充套件要測試的活動,覆蓋 startActivity() 方法
class MyActivityTest {
class MonitoredMyActivity extends MyActivity implements MonitoringForStartActivity {
List<Intent> startActivityCalls = new ArrayList<Intent>();
@Override
List<Intent> startActivityCalls() {
return this.startActivityCalls;
}
@Override
boolean startActivity(Intent i) {
this.startActivityCalls.add(i);
}
}
MonitoredMyActivity activity = new MonitoredMyActivity();
@Test
public void _TestActivityStarted() {
activity.startSomeActivity();
assertThat(monitoredActivity, hasStartedActivity(intentMatching("start some activity")));
}
}
這是關於監控活動的總結
import android.content.Intent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import java.util.Iterator;
import java.util.List;
/**
* Matcher with a mix-in interface, to monitor 'startActivity()' calls.
*
* Boilerplate:
*
* class MonitoredMyActivity extends MyActivity implements MonitoringForStartActivity {
* List<Intent> startActivityCalls = new ArrayList<Intent>();
*
* @Override
* List<Intent> startActivityCalls() {
* return this.startActivityCalls;
* }
*
* @Override
* boolean startActivity(Intent i) {
* this.startActivityCalls.add(i);
* }
* }
*
* assertThat(monitoredActivity, hasStartedActivity(sameInstance(someIntent)));
*/
public class MonitoringForStartActivityTypeSafeDiagnosingMatcher extends TypeSafeDiagnosingMatcher<MonitoringForStartActivityTypeSafeDiagnosingMatcher.MonitoringForStartActivity>
{
public interface MonitoringForStartActivity
{
List<Intent> didCallStartActivity();
}
public static Matcher<MonitoringForStartActivity> hasNeverStartedActivity()
{
return new MonitoringForStartActivityTypeSafeDiagnosingMatcher();
}
public static Matcher<MonitoringForStartActivity> hasStartedActivity(final Matcher<Intent> matcher)
{
return new MonitoringForStartActivityTypeSafeDiagnosingMatcher(matcher);
}
public MonitoringForStartActivityTypeSafeDiagnosingMatcher(Matcher<Intent> ... matchers)
{
this.matchers = matchers;
}
private final Matcher<Intent>[] matchers;
@Override
protected boolean matchesSafely(MonitoringForStartActivityTypeSafeDiagnosingMatcher.MonitoringForStartActivity monitoredTestActivity, Description description)
{
final List<Intent> intents = monitoredTestActivity.startActivityCalls();
description.appendText(" startActivity was called " + intents.size() + " times");
if (intents.size() == 0)
{
description.appendText(" never");
}
else
{
description.appendText(" with");
for (Intent intent : intents)
{
description.appendText(": " + intent);
}
}
if (intents.size() != matchers.length)
{
return false;
}
boolean matchesAll = true;
Iterator<Intent> eachIntent = intents.iterator();
for (Matcher<Intent> matcher : matchers)
{
matchesAll = matchesAll && eachIntent.hasNext() && matcher.matches(eachIntent.next());
}
return matchesAll;
}
@Override
public void describeTo(Description description)
{
if (matchers.length == 0)
{
description.appendText(" never calls startActivity");
}
else
{
description.appendText(" calls startActivity with ");
for (Matcher<Intent> matcher : matchers)
{
description.appendDescriptionOf(matcher);
}
}
}
}