Android 测试 Robolectric NullPointerException 创建 PendingIntent

Android testing Robolectric NullPointerException creating PendingIntent

我正在尝试创建一种方法的测试,该方法清除数据库中的一些数据、取消一个现有的 AlarmManager(清除相同的 PendingIntent)并删除存储中的文件等。

测试基本上包括三个步骤: - 启动创建警报管理器并将数据放入数据库的方法 - 启动清除所有内容的方法 - 所有检查

当 Robolectric 尝试使用 NullPointerException 创建挂起的意图时,测试失败。

@Test
public void testClearExpiredVideoDownloadedContent() {

    mDatabase.post_action().addVideo(mVideoSample, StaticDbConfig.TableNames.DOWNLOADED_CONTENT);

    //Run the method to create the timer for downloaded content into the database
    int numberAlarmCreated = SuperBase.setUpContextExpireAlarm(mContext);
    assertEquals("Alarm has not been created", 1, numberAlarmCreated);

    //Run method to clear the expired content
    mDatabase.delete_action().clearExpiredVideoContent(mContext, mVideoSample);

    //ALL THE CHECKS
}

方法 setUpContextExpireAlarm 在我使用未决意图时崩溃:

 Intent intent = new Intent(context, ExpiredContentReceiver.class);
            intent.putExtra(ExpiredContentReceiver.EXTRA_VIDEO_INFO, video);
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, video.getId(), intent, PendingIntent.FLAG_NO_CREATE);

            SimpleDateFormat format = new SimpleDateFormat(StaticAppConfig.MatDateFormat);
            Date d = format.parse(video.getExpiryDate());
            alarmMgr.setRepeating( //CRASHING HERE BECAUSE alarmIntent is null
                    AlarmManager.RTC_WAKEUP,
                    d.getTime(),
                    AlarmManager.INTERVAL_DAY,
                    alarmIntent);

编辑

这是创建警报管理器和未决意图的方法:

public static int setUpContextExpireAlarm(Context context){
    AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    ArrayList<VideosV0> videosV0s = new DatabaseHandler(context, null).get_action().getNotExpiredDownloadedContent();
    for(VideosV0 video : videosV0s){

        try {
            Intent intent = new Intent(context, ExpiredContentReceiver.class);
            intent.putExtra(ExpiredContentReceiver.EXTRA_VIDEO_INFO, video);
            PendingIntent alarmIntent = PendingIntent.getBroadcast(context, video.getId(), intent, PendingIntent.FLAG_NO_CREATE);

            SimpleDateFormat format = new SimpleDateFormat(StaticAppConfig.MatDateFormat);
            Date d = format.parse(video.getExpiryDate());
            alarmMgr.setRepeating(
                    AlarmManager.RTC_WAKEUP,
                    d.getTime(),
                    AlarmManager.INTERVAL_DAY,
                    alarmIntent);
            Logging.i("Setting up the alarm for content ["+video.getTitle()+" ("+video.getId()+")], the alarm will be triggered on ["+video.getExpiryDate()+"("+d.getTime()+")] ");
        } catch (ParseException e) {
            e.printStackTrace();
        }

    }
    return videosV0s.size();
}

这次通话:

PendingIntent alarmIntent = PendingIntent.getBroadcast(context,
        video.getId(), intent, PendingIntent.FLAG_NO_CREATE);

不会创建 PendingIntent。如果您指定 PendingIntent.FLAG_NO_CREATE 则不会创建 PendingIntent,如果已经有一个,它只会创建 return 个。

如果你想有多个闹钟,你需要确保 PendingIntent 是唯一的。删除标志 PendingIntent.FLAG_NO_CREATE 并确保在每个 Intent 上使用唯一的 ACTION 或在对 PendingIntent.getBroadcast() 的调用中使用唯一的 requestCode。这将确保它每次都创建一个新的。