samedi 11 mai 2019

How to mock network layer responses for automated Android Studio UI Espresso test suite?

My goal is to run a suite of Espresso UI Tests, and have the Retrofit instance that has been created in the onCreate method of my MainActivity reconfigured to return mocked JSON responses from localhost, so I can test how the app's UI responds to response codes and different JSON data, etc.

So far, I've tried to drop in the MockWebServer package, and I was able to get that up and running on a localhost server. However, the Retrofit instance was still configured to the production url.

I've tried passing arguments at the launch of a test, including manually setting the intent for the MainActivity with some extras, in an attempt to set a flag that could toggle the string used for the Retrofit instance. However, it seems that the any arguments set in @Before of a test don't get picked up at the launch of the MainActivity.

I've looked at these answers, but there doesn't appear to be a solution:

Android Espresso UI Test with mocked Retrofit API

Mock server requests Android Espresso UI Testing

This is my latest experiment:

@get:Rule
    var activityRule = ActivityTestRule(MainActivity::class.java, true, false)

    @Before
    fun setup() {

    }

    @Test
    fun intent() {
        val intent = Intent()

        activityRule.launchActivity(intent.putExtra("UITesting", true))

        println(activityRule.activity.intent.extras)
    }

Here is the Retrofit instance:

var BASE_URL = "https://api.invoicehome.com"

class NetworkManager {

    private val service : networkService
    // initialization with BASE_URL, using Gson converter factory to decode ( i believe there are other options available as well)
    init {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        service = retrofit.create(networkService::class.java)
//    }
    }
 }

Beginning of MainActivity, where there's an instance of the NetworkManager:

class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    private var networkManager = NetworkManager()
}

I would like something that could simply wrap around the instance of Retrofit, and pop in a URL, but I'm 99% sure this isn't realistic. If any swift devs are looking at this, I'm looking for analogous functionality to Swifter.

So, can I somehow make the URL conditional for the Retrofit instance? Where would I pass in these flags? Is there a library that I'm missing that can do all of this for me?

Aucun commentaire:

Enregistrer un commentaire