Android TDD Part 8— Instrumented Tests

Evan Chen
2 min readJul 25, 2020

--

Mock every android framework may not be a good idea because we don’t know if the app can run on real devices. In the previous sample, we mock SharedPreference to let the test run on JVM.

This article, we’ll introduce another way: Separate to unit test and Instrumented test.

First, create a SharedPreferenceManger which is to manage any process about SharedPreference.

The two parts:

Local Unit test: To test Repository.saveUserId interact with ISharedPreferenceManager.

Instrumented test: To test is SharedPreference saved data successfully.

Create a SharedPreferenceManager class that implements ISharedPreferenceManager interface. The method saveStringis used to save data by key. The method getString is used to get data by key.

class SharedPreferenceManager(override val context: Context) 
: ISharedPreferenceManager {

private val sharedPreferenceKey = "USER_DATA"
var sharedPreference: SharedPreferences
init {
sharedPreference =
context.getSharedPreferences(
sharedPreferenceKey, Context.MODE_PRIVATE
)
}
override fun saveString(key: String, value: String){
sharedPreference.edit().putString(key, value).commit()
}
override fun getString(key: String): String {
return sharedPreference.getString(key, "")
}
}

In the Repository, use constructor injection to pass ISharedPreferenceManager instance. Now, we can call sharedPreferenceManager.saveString to save data.

class Repository(
val sharedPreferenceManager: ISharedPreferenceManager
) {
fun saveUserId(id: String) {
sharedPreferenceManager.saveString("USER_ID", id)
}
}

Local Unit Test

To verify if repository call mockSharedPreferenceManager.saveString()

@Test
fun saveUserId() {
val mockSharedPreferenceManager
= mock(ISharedPreferenceManager::class.java)
val userId = "A1234567"
val preKey = "USER_ID"
val repository = Repository(mockSharedPreferenceManager)

//Act call repository.saveUserId()
repository.saveUserId(userId)

//Assert
verify(mockSharedPreferenceManager).saveString(preKey, userId)
}

Instrumented Test

In Instrumented Test, test if saved data successful.

@RunWith(AndroidJUnit4::class)
class SharedPreferenceManagerTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
val key = "User_Id"
val value = "A123456789"
val sharedPreferenceManager: ISharedPreferenceManager
= SharedPreferenceManager(appContext)
sharedPreferenceManager.saveString(key, value)

val valueFromSP = sharedPreferenceManager.getString(key)
//get data fromSharedPreference and verify it.
Assert.assertEquals(value, valueFromSP)
}
}

Run test, you can see an emulator or device is opened because it’s an Instrumented test. Although this kind of test takes most of the time, we still need an Instrumented test. Take both advance of unit test and instrumented test.

Github:
https://github.com/evanchen76/AndroidTDD_InstrumentedTestSample

Next: Android TDD Part 9 — UI Test: Espresso

--

--