unit test example all android mockito junit4

android - test - Necesitas ayuda para escribir una prueba unitaria usando Mockito y JUnit4



mockito verify (9)

¿Necesita ayuda para escribir una prueba de unidad para el siguiente código utilizando Mockito y JUnit4,

public class MyFragmentPresenterImpl { public Boolean isValid(String value) { return !(TextUtils.isEmpty(value)); } }

Probé el siguiente método: MyFragmentPresenter mMyFragmentPresenter

@Before public void setup(){ mMyFragmentPresenter=new MyFragmentPresenterImpl(); } @Test public void testEmptyValue() throws Exception { String value=null; assertFalse(mMyFragmentPresenter.isValid(value)); }

pero devuelve la siguiente excepción,

java.lang.RuntimeException: el método isEmpty en android.text.TextUtils no está simulado. Ver http://g.co/androidstudio/not-mocked para más detalles. en android.text.TextUtils.isEmpty (TextUtils.java) en ....


Como seguimiento a la respuesta de Johnny, para capturar también las llamadas TextUtils.isEmpty (null), puede utilizar este código.

PowerMockito.mockStatic(TextUtils.class); PowerMockito.when(TextUtils.isEmpty(any())) .thenAnswer((Answer<Boolean>) invocation -> { Object s = invocation.getArguments()[0]; return s == null || s.length() == 0; });


Deberías usar Robolectric:

testImplementation "org.robolectric:robolectric:3.4.2"

Y entonces

@RunWith(RobolectricTestRunner::class) class TestClass { ... }


Debido a que la clase JUnit TestCase no puede utilizar las API relacionadas con Android, tenemos que burlarnos de ella.
Utilice PowerMockito para PowerMockito de la clase estática.

Agrega dos líneas sobre tu clase de caso de prueba,

@RunWith(PowerMockRunner.class) @PrepareForTest(TextUtils.class) public class YourTest { }

Y el codigo de configuracion

@Before public void setup() { PowerMockito.mockStatic(TextUtils.class); PowerMockito.when(TextUtils.isEmpty(any(CharSequence.class))).thenAnswer(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { CharSequence a = (CharSequence) invocation.getArguments()[0]; return !(a != null && a.length() > 0); } }); }

Eso implementa TextUtils.isEmpty() con nuestra propia lógica.

Además, agrega dependencias en los archivos app.gradle .

testCompile "org.powermock:powermock-module-junit4:1.6.2" testCompile "org.powermock:powermock-module-junit4-rule:1.6.2" testCompile "org.powermock:powermock-api-mockito:1.6.2" testCompile "org.powermock:powermock-classloading-xstream:1.6.2"

Gracias a la Behelit de Behelit y Exception .


Este es un problema conocido como lo menciona @Exception. En mi caso, también me topé con la misma situación, pero por consejo del desarrollador senior decidió usar Strings.isNullOrEmpty() lugar de TextUtils.isEmpty() . Resultó ser una buena forma de evitarlo.

Actualización: debería mencionar que esta función de utilidad Strings.isNullOrEmpty() requiere una biblioteca de guava.


Este es un problema conocido, debido a una cláusula en Pruebas fundamentales de Android que dice:

Puede usar la clase JUnit TestCase para realizar pruebas unitarias en una clase que no llame a las API de Android.

El comportamiento predeterminado es problemático cuando se usan clases como Log o TextUtils .

Para resumir:

  1. android.jar es simulado antes, por lo que es posible que algunos valores de retorno de la API de Android no sean los esperados.
  2. JUnit en sí es una medida única para el código java, así que trate de no usar los métodos API de Android.

Fuente: http://www.liangfeizc.com/2016/01/28/unit-test-on-android/



Sustituyo a todas partes en mi proyecto TextUtils.isEmpty(...) con esto:

/** * Util class to be used instead of Android classes for Junit tests. */ public class Utils { /** * Returns true if the string is null or 0-length. * @param str the string to be examined * @return true if str is null or zero length */ public static boolean isEmpty(@Nullable CharSequence str) { return str == null || str.length() == 0; } }


Usa PowerMockito

Agregue esto sobre su nombre de clase, e incluya cualquier otro nombre de clase CUT (clases bajo prueba)

@RunWith(PowerMockRunner.class) @PrepareForTest({TextUtils.class}) public class ContactUtilsTest {

Agrega esto a tu @Antes

@Before public void setup(){ PowerMockito.mockStatic(TextUtils.class); mMyFragmentPresenter=new MyFragmentPresenterImpl(); }

Esto hará que PowerMockito devuelva los valores predeterminados para los métodos dentro de TextUtils

También deberías agregar las dependencias de gradle relevantes.

testCompile "org.powermock:powermock-module-junit4:1.6.2" testCompile "org.powermock:powermock-module-junit4-rule:1.6.2" testCompile "org.powermock:powermock-api-mockito:1.6.2" testCompile "org.powermock:powermock-classloading-xstream:1.6.2"


agrega esta línea en tu archivo de gradle en el caso de Android Studio.

android{ .... testOptions { unitTests.returnDefaultValues = true } }