跳转到内容

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);
			}
		}
	}
}
华夏公益教科书