Strategia di test per la classe wrapper

3

Nel mio progetto Android ho deciso di creare wrapper attorno a SharedPreferences (che è fondamentalmente l'archiviazione dei valori-chiave) con l'interfaccia seguente

interface Preferences{
    public void saveInt(int value, String key);
    public void saveString(String value, String key);
    public int readInt(String key);
    public String readString(String key);
}

Implemetation utilizza l'API Android SharedPreferences, la versione semplificata è simile a questa:

public class SharedPrefencesWrapper implements Preferences{
    private SharedPreferences mSharedPreferences;

    public SharedPreferencesStorage(Context context) {
        mSharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    }
    public void saveInt(int value, String key){
        mSharedPreferences.edit().putInt(key, value).commit();
    }
    //The same for all other public methods
}

Ora voglio testare la classe SharedPreferencesWrapper, ogni metodo pubblico della classe Preferences:

public class SharedPreferencesWrapperTest{
    @Test
    public void savesBoolean(){
       Preferences prefs = new SharedPreferencesWrapper(...);
       prefs.saveInt(3, "intKey");
       int savedValue = prefs.readInt("intKey");
       assertEquals(3, savedValue);
    }
}

Ora, il test può assomigliare a questo? O dovrei usare l'API SharedPreferences per controllare i valori salvati nei test? La mia preoccupazione è che per recuperare il valore userò i metodi di SharedPrefencesWrapper, qualcosa non sembra proprio qui.

    
posta Igor Filippov 01.06.2015 - 21:01
fonte

2 risposte

3

In teoria, vuoi assicurarti che i dati siano stati archiviati usando l'API SharedPreferences, e quindi, in teoria, dovresti controllare che i valori memorizzati usando il tuo wrapper siano disponibili quando vengono recuperati direttamente usando l'API.

In pratica, specialmente se intendi che tutto il tuo codice debba usare il tuo wrapper, potresti anche solo controllare che possa recuperare ciò che memorizza, in parte perché uno dei motivi "normali" per un wrapper è quello di permetterlo di cambiare il meccanismo di archiviazione sottostante, quindi in futuro potresti decidere di memorizzare le impostazioni in un database, ad esempio.

    
risposta data 03.06.2015 - 07:28
fonte
2

tecnicamente va bene testare una funzione con la sua funzione inversa. Il tuo test di integrazione di basso livello integra il tuo codice con la funzione Android sottostante. Dal momento che non è possibile prendere in giro la funzione Android sottostante, non è possibile scrivere un puro test unitario (test in isolamento).

Ma "...something doesn't feel right here." : sono d'accordo (almeno con il tuo esempio): questa astrazione e il suo test hanno davvero senso?

di solito non scrivo le unittest per semplici getter / setter / wrapper ma ho un test di integrazione di livello più alto che le usa. la scrittura di unittests per getter / setter / wrapper è troppo lavoro per troppi benefici.

Non vedo molto beneficio per l'astrazione di SharedPreferences che utilizza ancora "numeri magici" come "intKey" o costante corrispondente di it-s.

Secondo me un'astrazione di più alto livello ha più benefici. vale a dire. per le impostazioni vorrei usare

MySettingsViaSharedPreferences implements MySettings {
   boolean isDatabaseEnabled() {...}
   string getDatabaseUrl() {...}
    
risposta data 03.06.2015 - 11:53
fonte

Leggi altre domande sui tag