Skip to content

SDK bump to 14.0.0 causes unit test failures  #490

@matthewbahr-clear

Description

@matthewbahr-clear

Steps to Reproduce the Problem

Bumped SDK from 13.4.1 to 14.0.0

Expected Behavior

Unit tests continue working

Actual Behavior

Null pointer exceptions start to be thrown from Unit Tests because of null application context.

java.lang.NullPointerException: Cannot invoke "android.content.Context.getPackageName()" because the return value of "android.content.Context.getApplicationContext()" is null

Unit tests broke
java.lang.NullPointerException: Cannot invoke "android.content.Context.getPackageName()" because the return value of "android.content.Context.getApplicationContext()" is null
	at androidx.core.app.NotificationManagerCompat.areNotificationsEnabled(NotificationManagerCompat.java:374)
	at com.clearme.clearapp.notifications.NotificationChannelManager.isChannelEnabled(NotificationChannelManager.kt:49)
	at com.clearme.clearapp.notifications.NotificationChannelManager.isChannelEnabled(NotificationChannelManager.kt:40)
	at com.clearme.clearapp.notifications.NotificationChannelManagerTest.update channel tracking via analytics(NotificationChannelManagerTest.kt:105)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:112)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:40)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:60)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

Instabug integration code

Make sure to remove your app token.

SDK Version

14.0.0

Android Version

N/A

Device Model

N/A

[Optional] Project That Reproduces the Issue


My main request here is to know which downstream dependencies you might have bumped to cause this issue. Our minimum SDK version is already 28 so the bump to 19 shouldn't have caused issues.

This is affecting unit tests that do not use Instabug at all.

Example failing code:

  @Test
  fun `update channel tracking via analytics`() {
    val analytics = mock<Analytics>()
    val notificationChannelManager =
      Mockito.spy(
        object : NotificationChannelManager(
          mock(),
          mock(),
          analytics,
        ) {
          override val channelId: String = "channel_id"
          override val analyticsTrackingProperty: String = "analytics_property"
        },
      )

    whenever(notificationChannelManager.isChannelEnabled()).doReturn(true)

    notificationChannelManager.updateChannelTracking()

    verify(analytics, times(1)).globalProperties(
      mapOf(notificationChannelManager.analyticsTrackingProperty to "true"),
      true,
    )
  }

Notably the call whenever(notificationChannelManager.isChannelEnabled()).doReturn(true) is using a spy to handle a mocked context not being able to return the actual value that would be resolved by isChannelEnabled()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions