这是我项目中的BroadcastReceiver,我正在寻求单元测试.当用户打电话时,它会抓取电话号码,并设置开始新活动的意图,并传入电话号码.
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的单元测试看起来像这样:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这贯穿代码,但我希望我的测试能够检查意图是否已发送出去,并检查其上的电话号码.我该怎么做呢?
我还可以测试电话呼叫是否被取消(因为setResultData(null)行)?
tho*_*att 47
corlettk指出我在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;
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试用例现在看起来像这样:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
cor*_*ttk 27
马特,
听起来你需要模拟一个Context ...然后将你的方法交换到接受接口而不是具体的类:public void onReceive(IContext c, IIntent i)只是为了测试的目的.但是后面的Context和Intent类不是你的......他们是Android的...所以你不能"只是"让它们实现你的接口,所以你必须"包装"它们才能暴露你的界面,这是很多代码,而不是很多.很讨厌!!!
所以我开始怀疑以前是否有人经历过这一切,并为我们做过坚硬的工作......并且tada:http://developer.android.com/reference/android/test/mock/package-summary.html
干杯.基思.
小智 6
由于这个问题被要求嘲笑框架已经发展了很多.使用mockito,您现在不仅可以模拟接口,还可以模拟类.所以我建议通过模拟上下文并使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25777 次 |
| 最近记录: |