web-dev-qa-db-fra.com

Comment se moquer d'un SharedPreferences en utilisant Mockito

Je viens de lire sur les tests unitaires instrumentés dans Android et je me demande comment je peux me moquer d'un SharedPreferences sans aucune classe SharedPreferencesHelper comme ici

Mon code est:

public class Auth {
private static SharedPreferences loggedUserData = null;
public static String getValidToken(Context context)
{
    initLoggedUserPreferences(context);
    String token = loggedUserData.getString(Constants.USER_TOKEN,null);
    return token;
}
public static String getLoggedUser(Context context)
{
    initLoggedUserPreferences(context);
    String user = loggedUserData.getString(Constants.LOGGED_USERNAME,null);
    return user;
}
public static void setUserCredentials(Context context, String username, String token)
{
    initLoggedUserPreferences(context);
    loggedUserData.edit().putString(Constants.LOGGED_USERNAME, username).commit();
    loggedUserData.edit().putString(Constants.USER_TOKEN,token).commit();
}

public static HashMap<String, String> setHeaders(String username, String password)
{
    HashMap<String, String> headers = new HashMap<String, String>();
    String auth = username + ":" + password;
    String encoding = Base64.encodeToString(auth.getBytes(), Base64.DEFAULT);
    headers.put("Authorization", "Basic " + encoding);
    return headers;
}

public static void deleteToken(Context context)
{
    initLoggedUserPreferences(context);
    loggedUserData.edit().remove(Constants.LOGGED_USERNAME).commit();
    loggedUserData.edit().remove(Constants.USER_TOKEN).commit();
}

public static HashMap<String, String> setHeadersWithToken(String token) {
    HashMap<String, String> headers = new HashMap<String, String>();
    headers.put("Authorization","Token "+token);
    return headers;
}
private static SharedPreferences initLoggedUserPreferences(Context context)
{
    if(loggedUserData == null)
        loggedUserData = context.getSharedPreferences(Constants.LOGGED_USER_PREFERENCES,0);
    return loggedUserData;
}}

Est-il possible de se moquer de SharedPreferences sans créer d'autre classe dessus?

21
adamura88

Donc, parce que SharedPreferences vient de votre context, c'est facile:

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

par exemple, pour getValidToken(Context context), le test pourrait être:

@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();
}
56
user180100

L'exemple suivant montre comment vous pouvez créer un test unitaire qui utilise un objet Contexte factice tel qu'une préférence partagée.

@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
   }
}

Si vous rencontrez des problèmes lors de l'importation de la maquette, assurez-vous d'avoir ajouté les dépendances dans votre app/build.gradle fichier.

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


Si vous souhaitez utiliser la véritable préférence partagée comme appareil en stockant toutes les données en mémoire, suivez le code ci-dessous.

Obtenez le fichier MockSharedPreference.Java à partir de ce 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);
}
1
Googlian