跳轉到內容

Android/測試/單元測試/監控超類方法

來自 Wikibooks,開放的書籍,開放的世界

一些監控行為很常見:例如,活動可以啟動其他活動,測試這些呼叫涉及記錄測試期間發出的意圖。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);
			}
		}
	}
}
華夏公益教科書