1

I have an activity for holding a fragment. I created this for being able to run Deep Link to the profile. Also I pass PROFILE_ID as a query parameter. So the whole deep link looks this: "tigranes://home/profile?profileId=3545664".

class ProfileActivity : BaseActivity() {

    companion object {
        @JvmStatic
        fun newInstance(context: Context, profileId: String): Intent {
            val intent = Intent(context, ProfileActivity::class.java)
            intent.putExtra(ProfileFragment.PROFILE_ID, profileId)
            return intent
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)

        val profileId: String = intent.getStringExtra(ProfileFragment.PROFILE_ID)
        val transaction = supportFragmentManager.beginTransaction()
        val fragment = ProfileFragment.newInstance(profileId)
        transaction.add(R.id.fragment_container, fragment)
        transaction.commit()
    }
}

So my question is what will be the best strategy for writing test checking if this deep link is opening ProfileActivity. I tried to use ActivityTestRule but I wasn't able to find a way for passing a parameters to it.

burkinafaso3741
  • 1,000
  • 1
  • 10
  • 15
  • 1
    The way you are creating your fragment is incorrect. You should be doing the initial FragmentTransaction inside `if(savedInstanceState == null` otherwise you will have overlapping fragments. – EpicPandaForce Jan 26 '20 at 20:37
  • I know :) The question is how to test deep links. – burkinafaso3741 Jan 26 '20 at 21:09
  • @TigranGhazinyan Answered that, but as the `ProfileActivity ` looks alike, it might not lead to the desired result... you could still validate the answer by calling `getIntent()`. – Martin Zeitler Jan 26 '20 at 21:33

1 Answers1

2

Method newInstance() seems to be utter non-sense, because the Intent is being passed to the Activity; you should reconsider how that ProfileActivity is being constructed, because this is not how it works. getIntent() is all you need to get the Intent (as the method's name might suggest). Also @EpicPandaForce's suggestion should be taken into consideration, in order to avoid a mess. However, this wasn't the actual question (just telling, because you might claim "it doesn't work").


Testing an Activity with a deep-link Intent works alike this:

import android.content.Intent
import android.net.Uri
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class ProfileActivityTest {

    @get:Rule
    var testRule = activityScenarioRule<ProfileActivity>(
        Intent(Intent.ACTION_VIEW, Uri.parse(DEEP_LINK))
    )

    @Test
    ...

    companion object {
        val DEEP_LINK = "tigranes://home/profile?profileId=3545664"
    }
}

The activityScenarioRule depends on:

androidTestImplementation "androidx.test.ext:junit-ktx:1.1.1"

Please let me know if this works (this would require fixing the ProfileActivity in the first place).

Also make sure, that the intent-filter in the AndroidManifest.xml is setup properly.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • This doesn't work for scenarios where DEEP_LINK is wrong i.e should have `ActivityNotFoundException`. @Martin Zeitler – Otieno Rowland Jul 20 '21 at 18:51
  • The deep-link cannot be wrong, because of an `intent-filter` in the `AndroidManifest.xml`.., which means your test case is absurd and invalid, because an `intent-filter` would never pick up an unknown URL. – Martin Zeitler Jul 21 '21 at 03:38
  • 1
    Over here, I thought tests are a safety net for absurd and invalid cases :) – Otieno Rowland Jul 21 '21 at 17:58