'Android, Test a function with mock context that need to access an activity

I'm trying to write unit test for this class :

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) //NullPointerException Here (probably for argument intent2)

        //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())
    }
}

So I tried this :

class ReminderBroadcastReceiverTest {


    private var mReminderBroadcastReceiver: ReminderBroadcastReceiver? = null
    private var mContext: Context? = null

    @Before
    @Throws(Exception::class)
    fun setUp() {
        mReminderBroadcastReceiver = ReminderBroadcastReceiver()
        mContext = mock(Context::class.java)
    }

    @Test
    fun testBroadcastReceiverSetTheNotification(){
        val titleText = "foo"
        val descrText = "foo is foo"
        val id = 12
        val intent = Intent(mContext, ReminderBroadcastReceiver::class.java) //this create an intent of broadcast receiver
        //Adding extra parameter that will be used in the broadcast receiver to create the notification
        intent.putExtra("title", titleText)
        intent.putExtra("description", descrText)
        intent.putExtra("id", id)

        mReminderBroadcastReceiver!!.onReceive(mContext, intent)


        //here we're looking for the notificationManager that have been
        val notificationService: NotificationManager = mContext!!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager


        Assert.assertEquals(1, notificationService.activeNotifications.size)

        val notification: Notification = notificationService.activeNotifications[0].notification

        val contentIntent: PendingIntent = notification.contentIntent

        Assert.assertEquals(contentIntent, MainActivity::class.java.name)
    }
}

However, it throws a NullPointerException that occurs when I reach the point where I what to create an pendingIntent in the onReceive function (in the first snippet), it must come from the Intent of mainActivity that I'm trying to create which seems to be null. I think it's because mainActivity is not part of the mocking context but I'm not sure.

Any idea how to make this work?

here's the error detail :

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.intern()' on a null object reference
at android.os.Parcel.createExceptionOrNull(Parcel.java:2431)
at android.os.Parcel.createException(Parcel.java:2409)
at android.os.Parcel.readException(Parcel.java:2392)
at android.os.Parcel.readException(Parcel.java:2334)
at android.app.IActivityManager$Stub$Proxy.getIntentSenderWithFeature(IActivityManager.java:6818)
at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:463)
at android.app.PendingIntent.getActivity(PendingIntent.java:444)
at android.app.PendingIntent.getActivity(PendingIntent.java:408)
at com.github.multimatum_team.multimatum.ReminderBroadcastReceiver.onReceive(ReminderBroadcastReceiver.kt:25)
at com.github.multimatum_team.multimatum.ReminderBroadcastReceiverTest.testBroadcastReceiverSetTheNotification(ReminderBroadcastReceiverTest.kt:44)
... 31 trimmed
Caused by: android.os.RemoteException: Remote stack trace:
at android.content.Intent.readFromParcel(Intent.java:11139)
at android.content.Intent.<init>(Intent.java:11118)
at android.content.Intent$1.createFromParcel(Intent.java:11106)
at android.content.Intent$1.createFromParcel(Intent.java:11104)
at android.os.Parcel.readTypedObject(Parcel.java:3171)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source