Android TDD Part 7— Mock android framework

Evan Chen
2 min readJul 23, 2020

--

As we mentioned before, if tested object interacts with the Android framework, this test is an Instrumented test which means needs to be run on real devices or simulate. These kinds of tests will take the most time. This article, we'll introduce how to run tests as local tests by mocking the android framework.

From the previous registration sample, we want to save loginId after sign up success. SharedPreference is a good way to save data.

We already know it’s hard to test writing non UI logic in Activity. So, let's create a Repository to save data by using SharedPreference.

class Repository(val context: Context) {
// save UserId to SharePreference
fun saveUserId(id: String) {
val sharedPreference =
context.getSharedPreferences(
"USER_DATA", Context.MODE_PRIVATE)

sharedPreference.edit().putString("USER_ID", id).commit()
}
}

Call Repository(this).saveUserId(loginId) when sign up success in Activity.

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

send.setOnClickListener {
...

// sign up success, saveUserId
Repository(this).saveUserId(loginId)
}
}

Start testing

Add a dependency to MockK library.

dependencies {
testImplementation 'io.mockk:mockk:1.9.3'
}

Step:

  1. Mock Context and SharePreference.
  2. Use every returns to return mocking sharedPreference.
  3. Call tested object repository.saveUserId(userId).
  4. Use verify to check sharedPrefesEditor.putString() is pass right parameter.
  5. Use verify to check sharedPrefsEditor.commit() is called.
@Test
fun saveUserId() {

// 1. Mock Context and SharePreference
val sharedPrefs = mockk<SharedPreferences>(relaxed = true)
val sharedPrefsEditor =
mockk<SharedPreferences.Editor>(relaxed = true)
val context = mockk<Context>(relaxed = true)

// 2. Use every returns to return mocking sharedPreference.
every{context.getSharedPreferences(any(),any())}
.returns(sharedPrefs)
every{sharedPrefs.edit()}
.returns(sharedPrefsEditor)
every{sharedPrefsEditor.putString(any(), any())}
.returns(sharedPrefsEditor)

val userId = "A1234567"
val preKey = "USER_ID"

// 3. Call tested object repository.saveUserId(userId)
val repository = Repository(context)
repository.saveUserId(userId)

// 4. Use verify to check sharedPrefesEditor.putString() is pass right parameter.
verify{sharedPrefsEditor.putString(eq(preKey), eq(userId)) }

// 5. Use verify to check sharedPrefsEditor.commit() is called.
verify{sharedPrefsEditor.commit()}
}

Click the green triangle to run the test. You'll see the testing duration is 20ms. Running a local test takes less time than the Instrument test.

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

Next:
Android TDD Part 8 — Instrumented Tests

--

--