2016-04-25 19 views
6

So che è strano, ma questo è quello che ho.JUnit4 TextUtils.isEmpty() restituisce risultati diversi da String.isEmpty()

enter image description here

Sto scrivendo uno unit test per verificare la mia logica per un'applicazione Android. Durante l'esecuzione di test, vedo che non riesce su quella linea:

if (!TextUtils.isEmpty(fromFile))

Prima che if affermazione fromfile è uguale a "" (stringa vuota), ma in qualche modo passa sopra e si rompe con un altro logica che doesn Prevedo una stringa vuota.

Immergersi nel debug Ho visto che fromFile.isEmpty() restituisce il risultato corretto, ma TextUtils.isEmpty(fromFile) dice che non è vuoto.

codice sorgente aperto, vedo:

public static boolean isEmpty(@Nullable CharSequence str) { 
    if (str == null || str.length() == 0) 
     return true; 
    else 
     return false; 
} 

e String.java:

public boolean isEmpty() { 
    return value.length == 0; 
} 

Ho seguito configutation: JDK 1.8.0_77

vorrei evitare tutta la logica nell'app per supportare String.isEmpty() solo per passare il test, dal momento che ho bisogno di supportare il codice prima dell'API Android 9, dove String.isEmpty non è disponibile, e al quindi TextUtils.isEmpty() fare di più. Qualsiasi aiuto con chiarimenti e suggerimenti sarebbe utile.

Qualcuno ha affrontato? Come dovrei risolverlo? Grazie in anticipo!

risposta

7

Per tutti coloro che si troveranno ad affrontare in futuro:

ho capito questo con l'aiuto di uomo buono, che è legato alla configurazione di test di unità Android nel Gradle:

testOptions { 
    unitTests.returnDefaultValues = true 
} 

che indicava a una soluzione: sbarazzarsi delle dipendenze Android nella logica aziendale che si sta testando con JUnit (unit test).

Ho semplicemente sostituito android.text.TextUtils con il mio metodo che è nella classe MyStringUtils.java, che fa lo stesso.

problema era che da deault metodi Android ha fatto tornare impostazione predefinita i valori durante l'esecuzione di test di unità, e non ha in realtà controllare fromFile valore stesso, piuttosto che tornare stub valore/default.

+0

Ma è questo s una soluzione? Intendo per questo caso che hai solo TextUtils, ma cosa succede se usi SparsArrays e qualche altra implementazione di utility personalizzata fornita da Android? – karate

+0

l'idea dei puri test di JUnit è che devono essere usati contro POJO (Plain Old Java Object). 'SparseArray 'non sono Old Java. Se ce l'hai, puoi andare su http://robolectric.org/, che è assolutamente soddisfacente secondo google https://developer.android.com/training/testing/fundamentals.html –

1

TextUtils non è un metodo JUnit.Se avete bisogno di manipolare con TextUtils.isEmpty risposta o l'altro metodo, si può prendere in giro le cose come:

mockStatic(TextUtils.class); 
when(TextUtils.isEmpty(any(CharSequence.class))).thenAnswer(new Answer<Boolean>() { 
     @Override 
     public Boolean answer(InvocationOnMock invocation) throws Throwable { 
      CharSequence str = (CharSequence) invocation.getArguments()[0]; 
      if (str == null || str.length() == 0) 
       return true; 
      else 
       return false; 
     } 
    }); 

Non dimenticare di aggiungere TextUtils-PrepareForTest lista:

@PrepareForTest({TextUtils.class}) 

metodo di cui sopra anche funziona per la configurazione returnDefaultValues:

testOptions { 
    unitTests.returnDefaultValues = true 
} 
+0

Purtroppo non usiamo ' Powermock' e 'mockStatic' non sono applicabili. Siamo passati alla diversa architettura, dove le nostre classi Java sono POJO e non hanno dipendenze Android. Ci siamo anche mossi da metodi statici come "Utils.doSomething" e rimuovendo singleton. Questo ci dà un maggiore controllo della DI e della copertura del test. Per quanto ne so codecov non supporta ancora 'PowerMockito'. Ma grazie per la risposta, credo che molti sviluppatori lo troveranno utile. –

Problemi correlati