unit testing广播接收机?
这里是我的项目的BroadcastReceiver,我正在寻找unit testing。 当用户拨打电话时,它抓住电话号码,并build立一个意图开始一个新的活动,传递电话号码。
public class OutgoingCallReceiver extends BroadcastReceiver { @Override public void onReceive(Context xiContext, Intent xiIntent) { if (xiIntent.getAction().equalsIgnoreCase(Intent.ACTION_NEW_OUTGOING_CALL)) { String phoneNum = xiIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); Intent intent = new Intent(xiContext, MyActivity.class); intent.putExtra("phoneNum", phoneNum); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); xiContext.startActivity(intent); setResultData(null); } } }
到目前为止,我的unit testing看起来像这样:
public class OutgoingCallReceiverTest extends AndroidTestCase { private OutgoingCallReceiver mReceiver; @Override protected void setUp() throws Exception { super.setUp(); mReceiver = new OutgoingCallReceiver(); } public void testStartActivity() { Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890"); mReceiver.onReceive(getContext(), intent); } }
这是通过代码运行的,但是我希望我的testing能够检查意图是否已经发出,并检查它的电话号码。 我该怎么做呢?
我还可以testing电话被取消(由于setResultData(空)行)?
马特,
听起来就像你需要模拟上下文…然后交换你的方法接受接口,而不是具体的类: public void onReceive(IContext c, IIntent i)
,只是为了testing的目的。 但是,Context和Intent类不是你的,他们是Android的…所以你不能“只”使它们实现你的接口,所以你必须“包装”它们以便暴露你的界面,这是相当多的代码没有太大的收获。 非常好吃!
所以我开始怀疑是否有人经历过这一切,为我们做了一些艰苦的工作……以及tada: http : //developer.android.com/reference/android/test/mock/package-summary.html
干杯。 基思。
科利特指着我在Android的MockContext对象,这是诀窍。 我已经做了它的一个子类,TestContext,看起来像这样:
public class TestContext extends MockContext { private List<Intent> mReceivedIntents = new ArrayList<Intent>(); @Override public String getPackageName() { return "com.mypackage.test"; } @Override public void startActivity(Intent xiIntent) { mReceivedIntents.add(xiIntent); } public List<Intent> getReceivedIntents() { return mReceivedIntents; } }
我的testing案例现在看起来像这样:
public class OutgoingCallReceiverTest extends AndroidTestCase { private OutgoingCallReceiver mReceiver; private TestContext mContext; @Override protected void setUp() throws Exception { super.setUp(); mReceiver = new OutgoingCallReceiver(); mContext = new TestContext(); } public void testStartActivity() { Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890"); mReceiver.onReceive(mContext, intent); assertEquals(1, mContext.getReceivedIntents().size()); assertNull(mReceiver.getResultData()); Intent receivedIntent = mContext.getReceivedIntents().get(0); assertNull(receivedIntent.getAction()); assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum")); assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0); } }
由于这个问题被问到嘲笑框架已经发展了很多。 用mockito你现在可以嘲笑不仅接口,而且类。 所以我build议通过嘲笑一个上下文并使用ArgumentCapture来解决这个问题:
import static org.mockito.Mockito.*; public class OutgoingCallReceiverTest extends AndroidTestCase { private OutgoingCallReceiver mReceiver; private Context mContext; @Override protected void setUp() throws Exception { super.setUp(); //To make mockito work System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString()); mReceiver = new OutgoingCallReceiver(); mContext = mock(Context.class); } public void testStartActivity() { Intent intent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); intent.putExtra(Intent.EXTRA_PHONE_NUMBER, "01234567890"); mReceiver.onReceive(mContext, intent); assertNull(mReceiver.getResultData()); ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).startActivity(argument.capture()); Intent receivedIntent = argument.getValue(); assertNull(receivedIntent.getAction()); assertEquals("01234567890", receivedIntent.getStringExtra("phoneNum")); assertTrue((receivedIntent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0); } }
- 找不到com.google.android.gms:play-services:3.1.59 3.2.25 4.0.30 4.1.32 4.2.40 4.2.42 4.3.23 4.4.52 5.0.77 5.0.89 5.2.08 6.1。 11 6.1.71 6.5.87
- 默认“大”,“中”和“小”文本视图android的dpi值
- 自己定义的Layout,onDraw()方法没有被调用
- 错误StrictMode $ AndroidBlockGuardPolicy.onNetwork
- 如何在Android / iOS中释放组件
- 在用户关注它之前,TextInputLayout不显示EditText提示
- Android以编程方式隐藏/取消隐藏应用程序图标
- 在Scroll上隐藏RecyclerView / ListView上的ActionBar
- 我可以用volley做同步请求吗?