java – 可以在测试用例中注册接收器吗?
|
我想在单元测试中测试是否触发使用AlarmManager编程的报警,如果是,则在正确的时间内触发. 以下是要测试的接收器类. public class MockBroadcastReceiver extends BroadcastReceiver {
private static int numTimesCalled = 0;
MockBroadcastReceiver(){
numTimesCalled = 0;
}
@Override
public void onReceive(Context context,Intent intent) {
numTimesCalled++;
}
public static int getNumTimesCalled() {
return numTimesCalled;
}
public static void setNumTimesCalled(int numTimesCalled) {
MockBroadcastReceiver.numTimesCalled = numTimesCalled;
}
}
这是单元测试. programReceiver方法实际上属于主项目中的一个类,但是我已经将它包含在测试中,所以你不需要读这么多代码. public class ATest extends AndroidTestCase {
MockBroadcastReceiver mockReceiver;
@Override
protected void setUp() throws Exception {
mockReceiver = new MockBroadcastReceiver();
getContext().registerReceiver(mockReceiver,new IntentFilter());
}
@Override
protected void tearDown() {
getContext().unregisterReceiver(mockReceiver);
mockReceiver = null;
}
public void test(){
//We're going to program twice and check that only the last
//programmed alarm should remain active.
final Object flag = new Object();
MockBroadcastReceiver.setNumTimesCalled(0);
new Thread (){
@Override
public void run(){
programReceiver(getContext(),MockBroadcastReceiver.class,60000,60000);
SystemClock.sleep(20000);
programReceiver(getContext(),60000);
SystemClock.sleep(90000);
synchronized(flag){
flag.notifyAll();
}
}
}.start();
synchronized(flag){
try {
flag.wait();
} catch (InterruptedException e) {
}
}
assertEquals(1,MockBroadcastReceiver.getNumTimesCalled()); //should have been called at least once,but its 0.
}
private static void programReceiver(Context context,Class<? extends BroadcastReceiver> receiverClass,long initialDelay,long period){
Intent intent = new Intent(context,receiverClass);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent); //Cancel any previous alarm
alarmManager.setInexactRepeating (
AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + initialDelay,period,pendingIntent
);
}
}
当我执行测试方法时,接收器应该已经在setUp中动态注册.然后我编程相同的闹钟两次.我的意图是测试,只有最后一个警报仍然活跃,但我无法使接收器被呼叫.测试失败,因为它预计会被调用一次(或至少多次> = 1),但是模拟接收器中的计数器为0.我已经在onReceive方法中设置了一个断点,它永远不会击中.我还添加了日志记录,没有显示在logcat中.所以我100%肯定接收机没有被叫.我也尝试增加线程中的睡眠时间,因为setInexactRepeating非常不正确地触发,但是我可以等待年龄,但仍然没有被调用. 我也尝试在测试项目的清单中注册它,而不是以编程方式注册,结果是一样的. 为什么收件人不被叫? UPDATE 我现在试图通过调用sendBroadcast来让接收方运行,但是我处于死胡同.接收器不会被调用.我尝试了主应用程序上下文,测试用例上下文,甚至是ActivityInstrumentationTestCase2.试过还添加了WakeLocks和没有.没有办法得到它.我认为这可能是由于意图或意图过滤器中的一些标志引起的(android似乎真的很挑剔标志). 解决方法在android源代码中有一个 alarmManagerTest,它使用broadcastreceiver执行alarmManager.setInexactRepeating.主要区别是工作的android测试延迟了15分钟,而您的测试使用了1分钟的延迟. AlarmManager的Android文档说: public void setInexactRepeating (int type,long triggerAtMillis,long intervalMillis,PendingIntent operation) … 如果这意味着只允许15分钟的多边形,我并不舒服. 在我的Android 2.2手机上,不精确的定时器只有在15分钟内才能工作. (编辑:鄂州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
