Intent extras in Unit test Android Mockito
Asked Answered
M

3

13

I am trying to verify that specific extras are added to Intent, but all the time I get null for the Intent in Unit test Android. I have the following class that need to be test:

public class TestClass extends SomeNotifier {
        private Intent mIntent = new Intent("testintent");

        public TestClassConstructor(Context context) {
            super(context);
        }

        @Override
        public void notifyChange() {
            mIntent.putExtra("Key one", 22);
            mIntent.putExtra("Key two", 23);
            mIntent.putExtra("Key three", 24);
            getContext().sendBroadcast(mIntent);
        }
    }

And the test is the following (I tried with mockIntent as well, but the result is the same, again the extras are null):

@RunWith(MockitoJUnitRunner.class)
public class TestClassTest {

  @Mock
  Context mMockContext;

  @Test
  public void sendBroadcastTest() {

  ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);

  TestClass testClassNotifier = new TestClass (mMockContext);
  testClassNotifier.notifyChange();
  verify(mMockContext).sendBroadcast(argument.capture());


 Intent intent = argument.getValue();
 //THE INTENT IS NULL
 Assert.assertTrue(intent.hasExtra("Key one"));

    }
}

Do you have any suggestion how should I make this test to work? Thanks in advance

Maintopmast answered 28/9, 2017 at 12:21 Comment(0)
S
2

Since you are trying to test and make assertions about an Intent object that is part of the Android framework and not just using it as a dependency, where you could simply mock it, vanilla unit tests won't work because the Android framework objects are simply 'empty' test double in unit tests.

This unit test + Android framework objects' limitation is explained better here.

You can achieve what you want by using a library such as Robolectric, that enable testing Android framework classes without using an emulator or device. The documentation has an example of assertions with an Intent instance that can guide you to do what you want :)

Sustenance answered 22/10, 2023 at 23:20 Comment(0)
R
0

You can use Mockk for mocking intent

 @Test
fun `Test`() {
    // Arrange
    val longValue = 1000L
    val enumValue = ModelEnum.MODEL1
    val intentMock = spyk<Intent>()
    every { intentMock.extras?.getLong("KEY_LONG_VALUE") } returns longValue
    every { intentMock.hasExtra(CheckoutRouter.RESULT_PAYMENT_TYPE) } returns true
    every { intentMock.getSerializableExtra("KEY_ENUM_VALUE") } returns enumValue

    // Action
    val a = A(intent = intentMock)
    val longValueResult = a.getLongValue()
    val enumValueResult =  a.getEnumValue()

    // Assert
    Assert.assertEquals(longValue, longValueResult)
    Assert.assertEquals(enumValue, enumValueResult)
}

class A (val intent: Intent){

    fun getLongValue():Long? {
        return intent.extras?.getLong("KEY_LONG_VALUE")
    }

    fun getEnumValue():ModelEnum? {
        return intent.getSerializableExtra("KEY_ENUM_VALUE") as? ModelEnum
    }
}

enum class ModelEnum{
    MODEL1,MODEL2
}
Ransell answered 28/8, 2023 at 18:38 Comment(0)
B
0

You can write unit test for processIntentExtras using Mockito and JUnit:

        @RunWith(MockitoJUnitRunner::class)
        class MyActivityTest {

            @Mock
            private lateinit var intent: Intent

            private lateinit var myActivity: MyActivity

            @Before
            fun setup() {
                MockitoAnnotations.initMocks(this)
                myActivity = MyActivity()
            }

            @Test
            fun testProcessIntentExtras() {
                // Prepare the mock intent with extras
                `when`(intent.getIntExtra("my_key", 0)).thenReturn(42)

                // Call the method to be tested
                myActivity.processIntentExtras(intent)

                // Add your assertions here to verify the processing logic
            }
        }
Boxhaul answered 25/10, 2023 at 6:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.