开发者

How to mock PreferenceManager in Android?

开发者 https://www.devze.com 2023-01-09 03:12 出处:网络
I\'ve written a class that is using Context, a thi开发者_Go百科rd party library and SharedPreferences from PreferenceManager.

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:

  1. A mock SharedPreferences, in which case you can just mock Context#getSharedPreferences (which is called by PreferenceManager#getDefaultSharedPreferences anyhow). You'll probably also have to make a mock SharedPreferences.Editor if preferences are edited, as above. You say you already know how to mock the context, so this should be fairly straightforward.

  2. 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().

0

精彩评论

暂无评论...
验证码 换一张
取 消