'Testing Intent that will be triggered by an alarm
I'm trying to set unit test for my android app. I have to test a notifications services that looks like that :
This class provide function to set notification in a context
class DeadlineNotification {
companion object {
private lateinit var alarmManager: AlarmManager
private lateinit var pendingIntent: PendingIntent
/*
Create a notification channel for reminder notifications
Creating an existing notification channel with its original values performs no operation,
so it's safe to call this code when starting an app.
*/
fun createNotificationChannel(context: Context){
val channelName :CharSequence = "reminders channel"
val description = "channel for reminders notifications"
val channel = NotificationChannel("remindersChannel", channelName, NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = context.getSystemService(NotificationManager::class.java)
channel.description=description
notificationManager.createNotificationChannel(channel)
}
/*
Set a notification that will be triggered in a given time in ms.
you can pass a title/description and Id in parameter
*/
fun setNotification(timeMS: Long, title: String, description: String, id: Int, context: Context){
alarmManager = context.getSystemService(AppCompatActivity.ALARM_SERVICE) as AlarmManager //this get an service instance of AlarmManager
val intent = Intent(context, ReminderBroadcastReceiver::class.java) //this create an intent of broadcast receiver
//Adding extra parameter that will be used in the broadcase receiver to create the notification
intent.putExtra("title", title)
intent.putExtra("description", description)
intent.putExtra("id", id)
//set the receiver as pending intent
pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_IMMUTABLE)
//set an alarm that will wake up the pending intent (receiver)
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeMS, pendingIntent)
}
fun getAlarmManager():AlarmManager = this.alarmManager
}
}
setNotification will set an Alarm that will launch an intent of ReminderBroadcastReceiver :
//this class is a BroadcastReceiver that will send a notification when it is triggered
class ReminderBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
var channelId = "remindersChannel"
//retrieving some parameters for the notification
var title = intent!!.getStringExtra("title")
var content = intent!!.getStringExtra("description")
var notifId = intent!!.getIntExtra("id", 0)
val intent2 = Intent(context, MainActivity::class.java)
intent2!!.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
//this is the intent where the user will be send when clicking on the notification
val pendingIntent = PendingIntent.getActivity(context, 0, intent2, PendingIntent.FLAG_IMMUTABLE)
//Builder of the notification
val notifBuilder = NotificationCompat.Builder(context!!, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(title + notifId.toString())
.setContentText(content)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
//send the notification
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(notifId, notifBuilder.build())
}
}
This will create a NotificationManager and send the notification.
The code above is working as expected.
Now I'm trying to write unit test for it, I tried this :
@RunWith(AndroidJUnit4::class)
class DeadlineNotificationTest {
@Test
fun `notification is triggered at currentTime and redirect to MainActivity`() {
val activity: MainActivity = Robolectric.setupActivity(MainActivity::class.java) //main Activity
DeadlineNotification.setNotification(System.currentTimeMillis(), "title", "empty description", 1, activity) //this create an alarm
//here we're looking for the notificationManager that have been
val notificationService: NotificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val shadowNotificationManager =
shadowOf(notificationService)
assertEquals(1, shadowNotificationManager.size())
val notification: Notification = shadowNotificationManager.allNotifications[0]
val contentIntent: PendingIntent = notification.contentIntent
val nextIntent = shadowOf(contentIntent).savedIntent
val nextClassName = nextIntent.component!!.className
assertEquals(nextClassName, MainActivity::class.java.getName())
}
}
But the first assertion fails, so I assume the shadowNotificationManager cannot see the notification. Do you have any Idea how I should proceed to have a working test?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
