Testing Activity Result Contract by Decoupling them from Activity Code

Hey folks,
I am here with a new article about a better way to write contracts.
In this article, I am going to give you details about how you can test activity results contracts. First thing first, never test contracts directly from the activity, you need to write them in a seprate file and send ActivityResultRegistry as a parameter so you can easily make your own ActivityResultRegistry with the expected result and other details so you can fake this functionality.
If you haven’t read my last article about contracts where I explained the custom contracts to abstract our work and decouple the code. I will highly recommend you to read my last article on custom contracts to get a good understanding of contracts’ thought processes.
Ok so in the last article we wrote a custom contract in a separate file but it was directly being register in activity. In this article, I am going to make an extra layer to abstract my contract logical part to separate my logic from my view.
Your contract file will be like
//Injecting my ActivityResultRegistry here using Hilt class ImageContractHandler @Inject constructor (registry: ActivityResultRegistry) { private val contractUriResult : MutableLiveData = MutableLiveData(null) private val getPermission = registry.register(REGISTRY_KEY, GetContentFileUri()) { uri -> contractUriResult.value = uri } fun getImageFromGallery(): LiveData { getPermission.launch("image/*") return contractUriResult } companion object { private const val REGISTRY_KEY = "Image Picker" } }
Hilt Module will look like this
@Module @InstallIn(ActivityComponent::class) class AppModule { @Provides fun provideActivityResultRegistry(@ActivityContext activity: Context) = (activity as? AppCompatActivity)?.activityResultRegistry ?: throw IllegalArgumentException("You must use AppCompatActivity") }
Contract consumer (MainActivity) will look like this
@AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var contractHandler : ImageContractHandler .................................................................. //So we have converted our contract call to single function private fun onGalleryClick() { contractHandler.getImageFromGallery().observe(this, { it?.let { u -> backgroundImageView.setImageURI(u) val file = File(u.path) } }) } .................................................................. }
Then comes your Android Test where you actually test the contract instead of testing the main activity to call the actual onGalleryClick method we already have a contract in a separate file so we can test it in isolation
@RunWith(AndroidJUnit4::class) @LargeTest class MainActivityTest { @get:Rule var instantTaskExecutorRule: InstantTaskExecutorRule = InstantTaskExecutorRule() @get:Rule var activityScenarioRule = ActivityScenarioRule( MainActivity::class.java ) ..................................................................................... @Test fun activityResultTest() { // Create an expected result URI val testUrl = "file//dummy_file.test" val expectedResult = Uri.parse(testUrl) // Create the test ActivityResultRegistry val testRegistry = object : ActivityResultRegistry() { override fun <I, O> onLaunch( requestCode: Int, contract: ActivityResultContract<I, O>, input: I, options: ActivityOptionsCompat? ) { dispatchResult(requestCode, expectedResult) } } val uri = ImageContractHandler(testRegistry).getImageFromGallery().getOrAwaitValue() assert(uri == expectedResult) } ..................................................................................... }
I’ve attached complete code for this article where you can find the detailed implementation of this concept for getting images from the gallery and then testing that functionality.
I’ve attached the Github code link so you can see the complete working example. This repository is used for both contracts articles and you can find code for the current article in decouple_test_hilt named branch
GitHub – UmairKhalid786/ImagePickerWithContentProvider at decouple_test_hilt
Contribute to UmairKhalid786/ImagePickerWithContentProvider development by creating an account on GitHub.
github.com
I hope you enjoyed this topic where I’ve explained a better way to write contracts so you can test it and then there is HILT helping in this cause as well.
If you enjoy this article, please subscribe and clap for me 😉 if you don’t then please write some feedback so I can improve in the given area.
Bye Bye
Share this article

Written by : admin
Latest Articles
June 21, 2024
June 11, 2024
June 10, 2024
May 31, 2024
May 27, 2024
May 10, 2024
February 1, 2024
December 28, 2023
December 26, 2023
December 18, 2023
December 15, 2023
September 26, 2023
September 21, 2023
September 19, 2023
September 19, 2023
September 12, 2023
September 5, 2023
August 29, 2023
March 31, 2023
March 20, 2023
March 13, 2023
March 13, 2023
March 13, 2023
March 13, 2023
March 13, 2023