
Member-only story
Testing Jetpack Security with Robolectric
When updating my Android caching library, layercache, with built-in support for the new Jetpack SecurityEncryptedSharedPreferences
I started to write unit tests using Robolectric, but soon came across the exception java.security.KeyStoreException: AndroidKeyStore not found
.
Usually, shadows come to mind when faced with issues like this, but in this article, we will discuss why this won’t work and how we can get around the problem to continue to write unit tests without requiring a test device.
What is Jetpack Security
The Security library implements crypto security best practices for storing data at rest and currently provides the classes EncryptedSharedPreferences
and EncryptedFile
.
EncryptedSharedPreferences
EncryptedSharedPreferences
is an implementation of SharedPreferences
where the keys and values are both encrypted.
To use, add the following dependency into yourbuild.gradle
file:
dependencies {
implementation("androidx.security:security-crypto:1.1.0-alpha01")
}
To create EncryptedSharedPreferences
, you first create a MasterKey
, default settings can be achieved with:
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
The MasterKey
can also be configured to ensure it is hardware backed as well as requiring user authentication. The documentation contains all the options.
Then you can create the EncryptedSharedPreferences
as follows:
val sharedPreferences = EncryptedSharedPreferences.create(
context,
"preference file name",
masterKey,
PrefKeyEncryptionScheme.AES256_SIV,
PrefValueEncryptionScheme.AES256_GCM
)
You can then read and write encrypted data seamlessly as if it were a normal SharedPreferences
file.
sharedPreferences.edit().apply {
putString("key", "value")
}.apply()
sharedPreferences.getString("key", "default") // returns "value"
Writing a unit test
We can start to write a simple test to ensure reading and writing to this…