I've written a class that is using Context
, a thi开发者_Go百科rd party library and SharedPreferences
from PreferenceManager
.
It's possible to mock Context
, the third party library can be mocked using some mocking framework, but what to do with PreferenceManager
?
I have two methods:
public void saveString(ThirdPartyObject obj) {
SharedPreferences appPreferences =
PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = appPreferences.edit();
editor.putString(mContext.getString(
R.string.preferences_string_name), obj.getString());
editor.commit();
}
and corresponding, that loads preferences.
It doesn't look like you actually want a mock instance of PreferenceManager
(which is mostly used in a PreferenceFragment
or PreferenceActivity
).
You probably want either:
A mock
SharedPreferences
, in which case you can just mockContext#getSharedPreferences
(which is called byPreferenceManager#getDefaultSharedPreferences
anyhow). You'll probably also have to make a mockSharedPreferences.Editor
if preferences are edited, as above. You say you already know how to mock the context, so this should be fairly straightforward.To use the actual preferences in the environment. This is easiest, and not necessarily a bad idea. Do make certain it's cleaned up properly so that your tests don't interfere with each other (or, depending on your test environment, aren't affected by manual use of the app).
If you really do want to mock PreferenceManager
instance (like that you get in PreferenceFragment
or PreferenceActivity
), you can absolutely do so.
Since it's non-final, you can generate a mock PreferenceManager
and SharedPreferences
using Mockito (or another mocking library) as long as you have a way to provide it to your code wherever you would ordinarily get one (in non-test code, this normally comes from the getPreferenceManager()
).
You can use specialized context for shared preference. RenamingDelegatingContext
delegates everything to a Context. When we access SharedPreference from a Context
, we use getSharedPreferences(String name, int mode)
.
Here by extending RenamingDelegatingContext
we override getSharedPreferences and pretend the name parameter with test PREFIX
, So when test runs it will write to preference file which is different then main application.
public class SpecializedMockContext extends RenamingDelegatingContext {
public static final String PREFIX = "test.";
public SpecializedMockContext(Context context) {
super(context, PREFIX);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return super.getSharedPreferences(PREFIX + name, mode);
}
}
Set this SpecialisedMockContext to your test Application context. setContext(specialisedMockContext)
and createApplication()
.
精彩评论