java – 可以在测试用例中注册接收器吗?

前端之家收集整理的这篇文章主要介绍了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
我可以确认AlarmManager不是问题.报警根据adb dumpsys报警正确注册.

我现在试图通过调用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)


interval之间的间隔间隔(以毫秒为单位).在API 19之前,如果这是INTERVAL_FIFTEEN_MINUTES之一,INTERVAL_HALF_HOUR,INTERVAL_HOUR,INTERVAL_HALF_DAY或INTERVAL_DAY,则报警将与其他报警相对齐,以减少唤醒次数.否则,报警将被设置为应用程序调用setRepeating(int,long,PendingIntent).从API 19开始,所有重复的报警将不准确,并与其他报警进行批处理,而不管其所述的重复间隔.

如果这意味着只允许15分钟的多边形,我并不舒服.

在我的Android 2.2手机上,不精确的定时器只有在15分钟内才能工作.

原文链接:https://www.f2er.com/java/125285.html

猜你在找的Java相关文章