Android Tests: Stubbing Out Retrofit con Mockito

En mi MainActivity tengo un método llamado getAPI que devuelve un OTBServiceWrapper . Esto se utiliza para configurar retrofit para llamar a una API.

En mi archivo MainActivityTest estoy intentando new OTBService().getService() la new OTBService().getService() que el método getApi está haciendo para poder devolver un MockedOTBService que cambia el cliente a uno personalizado que devuelve json .

Como es, la implementación actual será el MockedOTBService si tuviera que colocar un registrador dentro de MockedOTBService pero también cae y llama a la api real, que no es lo que quiero en una prueba.

Estoy tratando de stub las llamadas API de Retrofit usando Mockito y json retorno. No puedo entender por qué el talón se está llamando todavía no está stubbing el método en cuestión.

Notas:

  1. Estoy utilizando ActivityInstrumentationTestCase2
  2. Sólo estoy realizando una prueba
  3. Si agrego una verify(mockedOTBService, atLeastOnce()).getService(); Se dice que nunca fue llamado.
  4. Si cambio el when...thenReturn para usar un mMainActivity = spy(getActivity()) no hay cambio y se llama la API real.

Salida Logcat

 Logger﹕ MockedOTBService was called // Mock is called Logger﹕ Real OTBService was called // Real API is called Logger﹕ MainActivity getAPI method class is "$Proxy1" // Mock is shown in MainActivity Logger﹕ RealAPIResponse JSON Parsed ID: 266 // Real API response returned 

Flujo real

MainActivity.onCreate ()> OTBService.getService ()> OTBServiceWrapper.createSearch (…)

Tratando de lograr dentro de las pruebas

MainActivity.onCreate ()> MockedOTBService.getService ()> OTBServiceWrapper.createSearch (…)

MainActivity.java

 public class MainActivity extends Activity { private OTBServiceWrapper serviceWrapper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getApi().createSearch(...) } public OTBServiceWrapper getApi() { return new OTBService().getService(); } } 

OTBService.java

 public class OTBService { public OTBServiceWrapper getService() { RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(Constants.API_URL) .build(); return restAdapter.create(OTBServiceWrapper.class); } } 

OTBServiceWrapper.java

 public interface OTBServiceWrapper { @POST(Constants.API_SEARCHES_POST_URL) void createSearch(@Body Request request, Callback<Request.Response> callback); } 

MainActivityTest.java

 public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private OTBService mMockedOTBService; private MainActivity mMainActivity; private View mSearchButton; public MainActivityTest() { super(MainActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(true); System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().getCacheDir().getPath()); mMockedOTBService = mock(OTBService.class); when(mMockedOTBService.getService()).thenReturn(new MockedOTBService(getInstrumentation().getContext()).getService()); mMainActivity = getActivity(); mSearchButton = mMainActivity.findViewById(R.id.AbSearchButton); mYourHolidayButton = mMainActivity.findViewById(R.id.AbYourHolidayButton); } public void testButtonActions() { TouchUtils.clickView(this, mSearchButton); ... } } 

MockedOTBService.java

 public class MockedOTBService { private Context context; public MockedOTBService(Context context) { this.context = context; } public OTBServiceWrapper getService() { RestAdapter restAdapter; restAdapter = new RestAdapter.Builder() .setClient(new LocalJsonClient(context)) .setEndpoint(Constants.API_TEST_URL) .build(); return restAdapter.create(OTBServiceWrapper.class); } } 

LocalJsonClient.java

 @SuppressLint("DefaultLocale") public class LocalJsonClient implements Client { ... } 

Construir un gradiente

 dependencies { androidTestCompile 'com.google.dexmaker:dexmaker:1.0' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0' } 

Elimine la necesidad de burlarse de su solicitud permitiendo que la actividad establezca el servicio.

En su MainActivity cree una variable de clase y un setter de clase para el servicio. Debe estar en el ámbito de la clase para evitar que el método OnCreate se llame antes de haber configurado el servicio a lo que desea que sea. También crea un getter de instancia que establece el servicio si aún no lo has hecho.

En su prueba antes de llamar a getActivity() configure el servicio como su servicio de simulacro. (Tal vez pensar en mover esto a un objeto de apoyo).

MainActivity.java

 public class MainActivity extends Activity { private static OTBServiceWrapper serviceWrapper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getServiceWrapper.createSearch(...) } public OTBServiceWrapper getServiceWrapper() { if (serviceWrapper == null) { MainActivity.setServiceWrapper(new OTBService().getService()); } return serviceWrapper; } public static void setServiceWrapper(OTBServiceWrapper serviceWrapper) { MainActivity.serviceWrapper = serviceWrapper; } } 

MainActivityTest.java

 public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> { private MainActivity mMainActivity; public MainActivityTest() { super(MainActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(true); MainActivity.setServiceWrapper( new MockedOTBService(getInstrumentation().getContext()).getService() ); mMainActivity = getActivity(); } } 
  • ¿Cómo puedo interceptar un objeto observable y modificarlo en RxJava antes de volver al suscriptor?
  • Android: subir imagen a Twitter utilizando REST API y Fabric, error de tubería roto
  • Desmontaje de desmontaje de Retrofit + GSON
  • Retrofit 2.0 + RxJava + Error JSON cuerpo
  • ¿Cómo manejar los campos JSON opcionales en Retrofit para Android?
  • Retrofit - Los parámetros de @Body no se pueden usar con codificación de formularios o multipartes
  • Cómo poner en cola las llamadas de la API cuando no está conectado mientras usa Retrofit
  • AWS S3 Rest API con Android Retrofit V2 biblioteca, la imagen cargada está dañada
  • Error: tipos incompatibles: GsonConverterFactory no se puede convertir en Factory
  • Retrofit con Rxjava Schedulers.newThread () vs Schedulers.io ()
  • Consulta GET con json - Retrofit 2.0
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.