How to mock a SharedPreferences using Mockito

前端 未结 3 1540
夕颜
夕颜 2021-01-03 18:24

I have just read about Unit Instrumented Testing in Android and I wonder how I can mock a SharedPreferences without any SharedPreferencesHelper class on it like here

相关标签:
3条回答
  • 2021-01-03 19:17

    The following example shows how you might create a unit test that uses a mock Context object such as shared preference.

    @RunWith(MockitoJUnitRunner.class)
    public class MProfileTest {
    
       @Mock
       Context mockContext;
       @Mock
       SharedPreferences mockPrefs;
       @Mock
       SharedPreferences.Editor mockEditor;
    
       @Before
       public void before() throws Exception {
    
          Mockito.when(mockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mockPrefs);
          Mockito.when(mockContext.getSharedPreferences(anyString(), anyInt()).edit()).thenReturn(mockEditor);
    
          Mockito.when(mockPrefs.getString("YOUR_KEY", null)).thenReturn("YOUR_VALUE");
       }
    
       @Test
       public void anyTest() {
          // Any shared preference you can call
          // Assert.assertTrue();
          String val = _mockPrefs.getString("YOUR_KEY", null); // It returns YOUR_VALUE
       }
    }
    

    If you face any issues on importing mock framework just make sure you have added the depencencies in your app/build.gradle file.

    https://developer.android.com/training/testing/unit-testing/local-unit-tests#setup


    If you want to use real shared prefrence as your device by storing all the data in memory, follow the below code.

    Get the MockSharedPreference.java file from this Gist https://gist.github.com/aslamanver/f74a2b3d450fda251d47a0d38b44edb7

    @Mock
    Context mockContext;
    
    MockSharedPreference mockPrefs;
    MockSharedPreference.Editor mockPrefsEditor;
    
    @Before
    public void before() {
    
        mockPrefs = new MockSharedPreference();
        mockPrefsEditor = mockPrefs.edit();
    
        Mockito.when(mockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mockPrefs);
    }
    
    0 讨论(0)
  • 2021-01-03 19:17

    There is a better way to mock SharedPreferences, IMHO. I like Mockito, but it is unproductive to mock SharedPreferences in every test.

    Luckily, we can use the shared-preferences-mock library. This library implements SharedPrefences on JVM, so it behaves like a real class. Moreover, it is possible to write local unit tests.

    For your case:

    import com.github.ivanshafran.sharedpreferencesmock.SPMockBuilder;
    
    class Test {
        private Context context;
        private SharedPreferences sharedPreferences;
    
        @Before
        public void setUp() {
            this.sharedPreferences = new SPMockBuilder().createSharedPreferences();
            this.context = Mockito.mock(Context.class);         
            Mockito.when(context.getSharedPreferences(Constants.LOGGED_USER_PREFERENCES,0))
                .thenReturn(sharedPreferences);
        }
    
        @Test
        public void test() {
            sharedPreferences.edit().putString(Constants.LOGGED_USERNAME, "admin").commit();
            String value = Auth.getLoggedUser(context);
            asssertEquals("admin", value);
        }
    
    }
    
    

    Add it to your root build.gradle at the end of repositories:

    allprojects {
        repositories {
            maven { url 'https://jitpack.io' }
        }
    }
    

    Add the dependency:

    dependencies {
        testImplementation 'com.github.IvanShafran:shared-preferences-mock:1.0'
    }
    
    0 讨论(0)
  • 2021-01-03 19:24

    So, because SharedPreferences comes from your context, it's easy:

    final SharedPreferences sharedPrefs = Mockito.mock(SharedPreferences.class);
    final Context context = Mockito.mock(Context.class);
    Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
    
    // no use context
    

    for example, for getValidToken(Context context), the test could be:

    @Before
    public void before() throws Exception {
        this.sharedPrefs = Mockito.mock(SharedPreferences.class);
        this.context = Mockito.mock(Context.class);
        Mockito.when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(sharedPrefs);
    }
    
    @Test
    public void testGetValidToken() throws Exception {
        Mockito.when(sharedPrefs.getString(anyString(), anyString())).thenReturn("foobar");
        assertEquals("foobar", Auth.getValidToken(context));
        // maybe add some verify();
    }
    
    0 讨论(0)
提交回复
热议问题