I have a helper class to save user object to shared preferences. I have used a serialize(): String function and a create(serializedString: String) function in my User data model. They use GSon serializer and are working good as suggested by the unit tests on them.
Now my helper class is called SharedPreferenceUserStore.kt which takes a Context object. The code is:
class SharedPreferenceUserStore(context: Context) {
companion object {
val TAG = SharedPreferenceUserStore::class.java.simpleName
}
var userLocalSharedPref: SharedPreferences =
context.getSharedPreferences(USER_LOCAL_STORE_SHARED_PREF_NAME, Context.MODE_PRIVATE)
/*
Store the required data to shared preference
*/
#SuppressLint("ApplySharedPref")
fun storeUserData(user: User) {
val userLocalDatabaseEditor = userLocalSharedPref.edit()
val serializedData = user.serialize()
userLocalDatabaseEditor.putString(
USER_LOCAL_STORE_SHARED_PREF_SERIALIZED_DATA_KEY,
serializedData
)
if (userLocalDatabaseEditor.commit()) {
Log.d(TAG, " Store Commit return true")
}
}
/*
Clear all the locally stored data from the shared pref
*/
#SuppressLint("ApplySharedPref")
fun clearUserData() {
val userLocalDatabaseEditor = userLocalSharedPref.edit()
userLocalDatabaseEditor.clear()
userLocalDatabaseEditor.commit()
}
fun getLoggedInUser(): User? {
val stringUser = userLocalSharedPref.getString(
USER_LOCAL_STORE_SHARED_PREF_SERIALIZED_DATA_KEY, "")
return if (stringUser==null || stringUser == ""){
null
} else{
User.create(stringUser)
}
}
And I have written some unit tests for this helper class as follows:
#RunWith(JUnit4::class)
class SharedPreferenceUserStoreTest {
lateinit var sharedPreferenceUserStore: SharedPreferenceUserStore
lateinit var user: User
//to be mocked
lateinit var sharedPreferences: SharedPreferences
lateinit var sharedPreferencesEditor: SharedPreferences.Editor
lateinit var context: Context
#Before
fun setUp() {
//mocking Context and SharedPreferences class
context = mock(Context::class.java)
sharedPreferences = mock(SharedPreferences::class.java)
sharedPreferencesEditor = mock(SharedPreferences.Editor::class.java)
//specifying that the context.getSharedPreferences() method call should return the mocked sharedpref
`when`<SharedPreferences>(context.getSharedPreferences(anyString(), anyInt()))
.thenReturn(sharedPreferences)
//specifying that the sharedPreferences.edit() method call should return the mocked sharedpref editor
`when`(sharedPreferences.edit()).thenReturn(sharedPreferencesEditor)
//specifying that the sharedPreferencesEditor.putString() method call should return the mocked sharedpref Editor
`when`(sharedPreferencesEditor.putString(anyString(), anyString())).thenReturn(
sharedPreferencesEditor
)
`when`(sharedPreferences.getString(anyString(), anyString())).thenReturn("")
//instantiating SharedPreferenceUserStore from the mocked context
sharedPreferenceUserStore = SharedPreferenceUserStore(context)
user = User(
35,
"Prashanna Bhandary",
"prashanna.bhandary#gmail.com",
"dd58a617ea618010c2052cb54079ad67.jpeg",
"98********",
"test address 01",
1,
"yes",
"2019-08-30 04:56:43",
"2019-08-30 05:14:47",
0
)
}
#After
fun tearDown() {
}
#Test
fun passUser_storeUserData() {
sharedPreferenceUserStore.storeUserData(user)
verify(sharedPreferencesEditor).putString(
Constants.USER_LOCAL_STORE_SHARED_PREF_SERIALIZED_DATA_KEY,
user.serialize()
)
verify(sharedPreferencesEditor).commit()
}
#Test
fun testClearUserData() {
sharedPreferenceUserStore.clearUserData()
verify(sharedPreferencesEditor).clear()
}
#Test
fun testGetLoggedInUser_storeNotCalled() {
//calling getLoggedInUser() without calling storeUserData() should give null
assertEquals(null, sharedPreferenceUserStore.getLoggedInUser())
//verify that getString() was called on the shared preferences
verify(sharedPreferences).getString(Constants.USER_LOCAL_STORE_SHARED_PREF_SERIALIZED_DATA_KEY, "")
}
#Test
fun testGetLoggedInUser_storeCalled(){
//call getLoggedInUser(), we are expecting null
assertNull(sharedPreferenceUserStore.getLoggedInUser())
//verify that getString() was called on the shared preferences
verify(sharedPreferences).getString(Constants.USER_LOCAL_STORE_SHARED_PREF_SERIALIZED_DATA_KEY, "")
}
}
As I am really new to Unit Testing and Mocking libraries like Mockito. Now my question is are my tests any good? and I wanted to test if the getLoggedInUser() funciton of my helper class is doing what it is supposed to do (ie. get logged in user if shared pref has it), how do I do that?
In addition do suggest me any improvements I can make to my test or the helper class itself. Thank you.
Judging your test for what it is - A unit test running on a host machine with Android dependencies mocked with Mockito - it looks fine and like what you would expect.
The benefit-to-effort ratio of such tests are debatable, though. Personally I think it would be more valuable to run such a test against the real SharedPreferences implementation on a device, and assert on actual side effects instead of verifying on mocks. This has a couple of benefits over mocked tests:
You don't have to re-implement SharedPreferences with mocking
You know that SharedPreferenceUserStore will work with the real SharedPreferences implementation
But, such tests also have a debatable benefit-to-effort ratio. For a solo developer project, think about what kind of testing that is most important. Your time is limited so you will only have time to spend on writing the most important kind of tests.
The most important kinds of tests are the ones that test your app in the same way your users will use it. In other words, write high-level UI Automator tests. You can write how many mocked or on-device unit tests as you want. If you don't test that your entire app as a whole works, you will not know that it works. And if you don't know that your app as a whole works, you can't ship it. So in some way you have to test your app in its entirety. Doing it manually quickly becomes very labour intensive as you add more and more functionality. The only way to continually test your app is to automate the high-level UI testing of your app. That way you will also get code coverage that matters.
One big benefit of high-level UI testing that is worth pointing out is that you don't have to change them whenever you change some implementation detail in your app. If you have lots of mocked unit tests, you will have to spend a lot of time to refactor your unit tests as you refactor the real app code, which can be very time consuming, and thus a bad idea if you are a solo developer. Your UI Automator tests do not depend on low-level implementation details and will thus remain the same even if you change implementation details.
For example, maybe in the future you want to use Room from Android Jetpack to store your user data instead of SharedPreference. You will be able to do that without changing your high level UI tests at all. And they will be a great way to regression test such a change. If all you have are mocked unit tests, it will be a lot of work to rewrite all relevant unit tests to work with Room instead.
I agree with what #Enselic say about favoring Integration Test over Unit Tests.
However I disagree with his statement that this mockito test looks fine.
The reason for that is that (almost) every line in your code under test involves a mock operation. Basically mocking the complete method would have the same result.
What you are doing in your test is testing that mockito works as expected, which is something you should not need to test.
On the other hand your test is a complete mirror of the implementation itself. Which means everytime you refactor something, you have to touch the test. Preferably would be a black box test.
If you use Mockito you should try to restrict its use to methods that actually do something (that is not mocked).
Classes that generally should be mocked for testing purposes are dependencies that interact with external components (like a database or a webservice), however in these cases you are normally required to have Integration Tests as well.
And if your Integration-Tests already cover most part of the code, you can check whether you want to add a test using a mock for those parts that are not covered.
I have no official source for what I am trying to express, its just based on my experience (and therefore my own opinion). Treat it as such.
There is not much that can be said regarding the tests that guys before me haven't said.
However, one thing that you might want to consider is refactoring your SharedPreferenceUserStore to accept not Context(which is quite a huge thing, and if not handled properly could lead to unforeseen issues and/or memory leaks), but rather SharedPreferences themselves. This way, your class, that deals only with updating the prefs doesn't have access to more than it should.
Related
My goal is to test an app with Espresso.
First Screen Activity depends on settings received from a Repository. Repository checks whether the user saved a location preference in Shared Preferences. If he has, it moves on to the Main Activity. That's the part of logic that I am trying to test.
I want to substitute fake repository (HashMap representing shared preferences) to achieve consistency. Tests run and pass if the repository is empty (base state). However, I want to test whether the app moves forward if the location is saved.
Test in question:
#Test
fun onLaunch_withLocationSaved_checkMainActivityIsShown() {
fakeRepository.saveLocation("40,80")
ActivityScenario.launch(FirstScreenActivity::class.java)
onView(withText(R.string.welcome_message)).check(matches(not(isDisplayed())))
}
How do I get a reference to fakeRepository to be able to save location that ViewModel will read from?
If it's created (which defeats the point of injection) like this:
#Before
fun init() {
fakeRepository = FakeSimpleRepository()
fakeRepository.saveLocation("")
viewModel = FirstScreenViewModel(fakeRepository)
}
The viewmodel gets injected with a different fakeRepository object (I compared addresses with a debugger).
I followed Google's codelabs and official documentation how to set up Dagger with my app. Their examples do not show how to reference the repository though to make changes.
This blog cover what you want to achieve
The idea is that you have to override your dagger module to inject the mock object. Then you create a custom runner class to override the application class.
I'm trying to learn the Arrow library and improve my functional programming by transitioning some of my Android Kotlin code from more imperative style to functional style. I've been doing a type of MVI programming in the application to make testing simpler.
"Traditional" Method
ViewModel
My view model has a LiveData of the view's state plus a public method to pass user interactions from the view to the viewmodel so the view model can update state in whatever way is appropriate.
class MyViewModel: ViewModel() {
val state = MutableLiveData(MyViewState()) // MyViewState is a data class with relevant data
fun instruct(intent: MyIntent) { // MyIntent is a sealed class of data classes representing user interactions
return when(intent) {
is FirstIntent -> return viewModelScope.launch(Dispatchers.IO) {
val result = myRoomRepository.suspendFunctionManipulatingDatabase(intent.myVal)
updateStateWithResult(result)
}.run { Unit }
is SecondIntent -> return updateStateWithResult(intent.myVal)
}
}
}
Activity
The Activity subscribes to the LiveData and, on changes to state, it runs a render function using the state. The activity also passes user interactions to the view model as intents (not to be confused with Android's Intent class).
class MyActivity: AppCompatActivity() {
private val viewModel = MyViewModel()
override fun onCreateView() {
viewModel.state.observe(this, Observer { render(it) })
myWidget.onClickObserver = {
viewModel.instruct(someIntent)
}
}
private fun render(state: MyViewState) { /* update view with state */ }
}
Arrow.IO Functional Programming
I'm having trouble finding examples that aren't way over my head using Arrow's IO monad to make impure functions with side effects obvious and unit-testable.
View Model
So far I have turned my view model into:
class MyViewModel: ViewModel() {
// ...
fun instruct(intent: MyIntent): IO<Unit> {
return when(intent) {
is FirstIntent -> IO.fx {
val (result) = effect { myRoomRepository.suspendFunctionManipulatingDatabase(intent.myVal) }
updateStateWithResult(result)
}
is SecondIntent -> IO { updateStateWithResult(intent.myVal) }
}
}
}
I do not know how I am supposed to make this IO stuff run in Dispatcher.IO like I've been doing with viewModelScope.launch. I can't find an example for how to do this with Arrow. The ones that make API calls all seem to be something other than Android apps, so there is no guidance about Android UI vs IO threads.
View model unit test
Now, because one benefit I'm seeing to this is that when I write my view model's unit tests, I can have a test. If I mock the repository in order to check whether suspendFunctionManipulatingDatabase is called with the expected parameter.
#Test
fun myTest() {
val result: IO<Unit> = viewModel.instruct(someIntent)
result.unsafeRunSync()
// verify suspendFunctionManipulatingDatabase argument was as expected
}
Activity
I do not know how to incorporate the above into my Activity.
class MyActivity: AppCompatActivity() {
private val viewModel = MyViewModel()
override fun onCreateView() {
viewModel.state.observe(this, Observer { render(it) })
myWidget.onClickObserver = {
viewModel.instruct(someIntent).unsafeRunSync() // Is this how I should do it?
}
}
// ...
}
My understanding is anything in an IO block does not run right away (i.e., it's lazy). You have to call attempt() or unsafeRunSync() to get the contents to be evaluated.
Calling viewModel.instruct from Activity means I need to create some scope and invoke in Dispatchers.IO right? Is this Bad(TM)? I was able to confine coroutines completely to the view model using the "traditional" method.
Where do I incorporate Dispatchers.IO to replicate what I did with viewModelScope.launch(Dispatchers.IO)?
Is this the way you're supposed to structure a unit test when using Arrow's IO?
That's a really good post to read indeed. I'd also recommend digging into this sample app I wrote that is using ArrowFx also.
https://github.com/JorgeCastilloPrz/ArrowAndroidSamples
Note how we build the complete program using fx and returning Kind at all levels in our architecture. That makes the code polymorphic to the type F, so you can run it using different runtime data types for F at will, depending on the environment. In this case we end up running it using IO at the edges. That's the activity in this case, but could also be the application class or a fragment. Think about this as what'd be the entry points to your apps. If we were talking about jvm programs the equivalent would be main(). This is just an example of how to write polymorphic programs, but you could use IO.fx instead and return IO everywhere, if you want to stay simpler.
Note how we use continueOn() in the data source inside the fx block to leave and come back to the main thread. Coroutine context changes are explicit in ArrowFx, so the computation jumps to the passed thread right after the continueOn until you deliberately switch again to a different one. That intentionally makes thread changes explicit.
You could inject those dispatchers to use different ones in tests. Hopefully I can provide examples of this soon in the repo, but you can probably imagine how this would look.
For the syntax on how to write tests note that your program will return Kind (if you go polymorphic) or IO, so you would unsafeRunSync it from tests (vs unsafeRunAsync or unsafeRunAsyncCancellable in production code since Android needs it to be asynchronous). That is because we want our test to be synchronous and also blocking (for the latter we need to inject the proper dispatchers).
Current caveats: The solution proposed in the repo still doesn't care of cancellation, lifecycle or surviving config changes. That's something I'd like to address soon. Using ViewModels with a hybrid style might have a chance. This is Android so I'd not fear hybrid styles if that brings better productivity. Another alternative I've got in mind would maybe be something a bit more functional. ViewModels end up retaining themselves using the retain config state existing APIs under the hood by using the ViewModelStore. That ultimately sounds like a simple cache that is definitely a side effect and could be implemented wrapped into IO. I want to give a thought to this.
I would definitely also recommend reading the complete ArrowFx docs for better understanding: https://arrow-kt.io/docs/fx/ I think it would be helpful.
For more thoughts on approaches using Functional Programming and Arrow to Android you can take a look to my blog https://jorgecastillo.dev/ my plan is to write deep content around this starting 2020, since there's a lot of people interested.
In the other hand, you can find me or any other Arrow team maintainers in the Kotlinlang JetBrains Slack, where we could have more detailed conversations or try to resolve any doubts you can have https://kotlinlang.slack.com/
As a final clarification: Functional Programming is just a paradigm that resolves generic concerns like asynchrony, threading, concurrency, dependency injection, error handling, etc. Those problems can be found on any program, regardless of the platform. Even within an Android app. That is why FP is an option as valid for mobile as any other one, but we are still into explorations to provide the best APIs to fulfill the usual Android needs in a more ergonomic way. We are in the process of exploration in this sense, and 2020 is going to be a very promising year.
Hopefully this helped! Your thoughts seem to be well aligned with how things should work in this approach overall.
I've recently started getting into testing (TDD) and was wondering if anyone can shed some light into the practice I'm doing. For example, I'm checking if the location provider is available, I implement a contract (data source) class and a wrapper, like so:
LocationDataSource.kt
interface LocationDataSource {
fun isAvailable(): Observable<Boolean>
}
LocationUtil.kt
class LocationUtil(manager: LocationManager): LocationDataSource {
private var isAvailableSubject: BehaviorSubject<Boolean> =
BehaviorSubject.createDefault(manager.isProviderEnabled(provider))
override fun isAvailable(): Observable<Boolean> = locationSubject
}
Now, when testing, I'm not sure how to proceed. First thing that I did was mocking the LocationManager and the isProviderEnabled method:
class LocationTest {
#Mock
private lateinit var context: Context
private lateinit var dataSource: LocationDataSource
private lateinit var manager: LocationManager
private val observer = TestObserver<Boolean>()
#Before
#Throws(Exception::class)
fun setUp(){
MockitoAnnotations.initMocks(this)
// override schedulers here
`when`(context.getSystemService(LocationManager::class.java))
.thenReturn(mock(LocationManager::class.java))
manager = context.getSystemService(LocationManager::class.java)
dataSource = LocationUtil(manager)
}
#Test
fun isProviderDisabled_ShouldReturnFalse(){
// Given
`when`(manager.isProviderEnabled(anyString())).thenReturn(false)
// When
dataSource.isLocationAvailable().subscribe(observer)
// Then
observer.assertNoErrors()
observer.assertValue(false)
}
}
This works. However, during my research on how to do this and that, the time I spent figuring out how to mock the LocationManager was big enough to (I think) break one of the common rules in TDD -- a test implementation should not consume too much time.
So I figured, would it be best (and still within the TDD scope) to just test the contract (LocationDataSource) itself? Mocking dataSource and then replacing the test above with:
#Test
fun isProviderDisable_ShouldReturnFalse() {
// Given
`when`(dataSource.isLocationAvailable()).thenReturn(false)
// When
dataSource.isLocationAvailable().subscribe(observer)
// Then
observer.assertNoErrors()
observer.assertValue(false)
}
This would (obviously) provide the same result without going through the trouble of mocking a LocationManager. But, I think this defeats the purpose of the test -- since it only focuses on the contract itself -- and not the actual class that uses it.
I still think that maybe the first practice is still the proper way. That initially, it just takes time to familiarize with the mocking of Android classes. But I would love to know what the experts on TDD think.
Working backwards... this looks a little weird:
// Given
`when`(dataSource.isLocationAvailable()).thenReturn(false)
// When
dataSource.isLocationAvailable().subscribe(observer)
You've got a mock(LocationDataSource) talking to a TestObserver. That test isn't completely without value, but if I'm not mistaken running tells you nothing new; if the code compiles, then the contract is satisfied.
In a language where you have reliable type checking, executed tests should have a test subject that is a production implementation. So in your second example, if observer were a test subject, that would be "fine".
I wouldn't pass that test in a code review -- unless there is spooky recursion at a distance going on, there's no reason to mock a method call that you are going to be making in the test itself.
// When
BehaviorSubject.createDefault(false).subscribe(testSubject);
the time I spent figuring out how to mock the LocationManager was big enough to (I think) break one of the common rules in TDD -- a test implementation should not consume too much time.
Right - your current design is fighting with you when you try to test it. That's a symptom; your job as the designer is to identify the problem.
In this case, the code you are trying to test it too tightly coupled to the LocationManager. It is common to create an interface/contract that you can hide a specific implementation behind. Sometimes this pattern is called a seam.
LocationManager::isProviderEnabled, from the outside, is just a function that takes a String and returns a boolean. So instead of writing your method in terms of the LocationManager, write it in terms of the capability that it will give you:
class LocationUtil(isProviderEnabled: (String) -> boolean ) : LocationDataSource {
private var isAvailableSubject: BehaviorSubject<Boolean> =
BehaviorSubject.createDefault(isProviderEnabled(provider))
override fun isAvailable(): Observable<Boolean> = locationSubject
}
In effect, we're trying to push the "hard to test" bits closer to the boundaries, where we'll rely on other techniques to address the risks.
This is a serious question, I promise. I've spent the last 2 hours reading as many definitions of Mock that I could find and none explain this to me.
I've got a class I want to test and that class requires a mapper class as part of it's primary constructor:
open class PoiListViewModel #Inject constructor(
private val mapper: PoiMapper
) : ViewModel() {
In my unit test I have the following code:
//Mock objects needed to instantiate the class under test
#Mock lateinit var mapper: PoiMapper
// Class being tested
lateinit var poiListViewModel: PoiListViewModel
#Before
fun setup() {
MockitoAnnotations.initMocks(this)
poiListViewModel = PoiListViewModel(mapper)
}
My question to you all smart developers is, what exactly is a mock? And specifically how much of my original class does it replicate?
I'll tell you my assumed definition. A mock is a fake stand-in class that stands in for my real class, but that it does nothing except keep track of what method calls get sent to it. If I want the mock to have any functionality I need to stub that functionality in.
At least that's my ignorant view of mocks. But I'm apparently wront because in my unit test, my "mock" mapper class seems to be an actual mapper class. If I debug my unit test I see it walk through all the code of my mapper class. I see it returning converted data.
Here's the mapper class code (if it matters):
open class PoiMapper #Inject constructor() {
fun mockTest(num: Int): Int{
return num *23
}
fun mapToPresentation(domainModel: Poi_Domain): Poi_Presentation {
var test = 3
var results = mockTest(test)
return Poi_Presentation(domainModel.id,domainModel.name,domainModel.description,
domainModel.img_url,domainModel.latitude,domainModel.longitude,domainModel.imgFocalpointX,
domainModel.imgFocalpointY,domainModel.collection,domainModel.collectionPosition,
domainModel.release,domainModel.stampText)
}
}
Can someone explain it to me, how much of a mock is a Mockito mock? Did I instantiate the mocks incorrectly? Can someone give me a better way to think of mocks so I can wrap my head around all this?
Your understanding of mocks is correct. You're bumping into Kotlin's final-by-default behavior, as an implementation detail of Mockito.
Mockito mocks (as distinct from Mockito spies) are defined to take the place of your class instance. Unless you've stubbed them to return otherwise, they record all interactions and return default dummy values (zero, an empty string, an empty list, null, etc). You can confirm that they collaborated correctly with your system-under-test by stubbing return values (when/thenReturn), stubbing specific behaviors for methods (when/thenAnswer), or by checking that certain methods were called (verify) and retrieving the specific instances they were called with (ArgumentCaptor).
Under the hood, Mockito achieves this by generating a subclass of the class you're mocking, and overriding all methods to delegate to Mockito's internal handler. This is what gives Mockito the power to override the behavior silently: Your system-under-test thinks it's calling your dependency, but your code is using Java's virtual method dispatch to override your dependency's behavior.
Here's the trick: Java methods are virtual by default, unless you mark them final. In Kotlin, functions are closed by default, unless you mark them open. (I'm going to keep calling them final, because that's the definition at play in the JVM or Android Dexer, which is reading the bytecode that Kotlin generates anyway.) When the virtual machine is sure of a reference's type based on static typing, and you're calling a final method, the compiler is allowed to inline that implementation's code (JLS 8.4.3.3) because you've asserted that the method cannot be overridden and any code that tries to override it will fail at compilation. Mockito's generated code isn't compiled this way, and Mockito can't detect this case.
In your case, mapToPresentation is not open, so the compiler sees it as final and does not keep the virtual method dispatch that would let Mockito override the behavior. Your definition of mocking is right, and your code would be right, except that Kotlin is closed-by-default where Java is open-by-default. Besides, you really do rely on the function being open, because you'd like it to be called with a different implementation than the one in the function.
Trivially, you could just make all functions open that you intend to override, or use Mockito 2.1+'s built-in feature to mock final methods. However, as a general best practice you want an object that behaves like a PoiMapper even if it doesn't follow your specific PoiMapper implementation. That might be a good reason for an interface/impl split, such that your class PoiListViewModel takes a PoiMapper interface. In production you can provide a PoiMapperImpl as you have, but Mockito can generate an arbitrary implementation of the PoiMapper interface without worrying about whether PoiMapperImpl and its functions are open or closed.
Have you added the annotation
#RunWith(MockitoJUnitRunner.class)
to your test class?
I have a token property in my application class(Kotlin) that is based on a SharedPreferences value
var token : String?
get() = PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getString(TOKEN_PEREF_TAG, null)
set(value) {
PreferenceManager.getDefaultSharedPreferences(applicationContext)
.edit()
.putString(TOKEN_PEREF_TAG, value)
.apply()
}
The problem is that I can't set a mock value like this:
whenever(app.token).thenReturn("token")
since I get the error
java.lang.RuntimeException: Method getDefaultSharedPreferences in android.preference.PreferenceManager not mocked.
Shouldn't the mock just return the provided string?
how can I get around this error?
You can fix this error by using the mockito-inline dependency instead of the mockito-core dependency. This uses a different mocking method that circumvents this issue of the platform classes not being available. It's also particularly useful because it allows you to mock final classes, therefore eliminating the need to put every one of your classes behind an interface or mark them as open in Kotlin.
This inline mocking method can also be turned on by a configuration file, however I found just using the inline dependency much more reliable.
In a 'small test' (jUnit test, the one in src/test) the android framework is not present and the whole framework is just a stub and provides no functionality. You either have to create your own mocked SharedPreferences and PreferenceManager using mockito or sth similar. Or use an 'medium test' (instrumented test, the one in src/androidTest) which must run on emulator or a device. For more on this check Fundamentals of Testing