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
.
- Retrofit que lanza IllegalArgumentException exception for asynchronous FormUrlEncoded DELETE call
- MalformedJsonException con API de Retrofit?
- Retrofit 2 tutorial ejemplo, pero GsonConverterFactory error de visualización "No se puede resolver el símbolo"
- Android - Configuración de Retrofit / Apache HttpClient para Digest Auth
- La fábrica del convertidor de retroadaptación no puede acceder a GsonConverterFactory
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:
- Estoy utilizando
ActivityInstrumentationTestCase2
- Sólo estoy realizando una prueba
- Si agrego una
verify(mockedOTBService, atLeastOnce()).getService();
Se dice que nunca fue llamado. - Si cambio el
when...thenReturn
para usar unmMainActivity = 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' }
- Cómo enviar datos JSON como Cuerpo usando Retrofit android
- ¿Cómo determinar si se está ejecutando una solicitud determinada?
- Retrofit 2 cómo obtener la respuesta de objetos anidados json (android)
- Android: Realm + Retrofit - Serializar apiresponse
- Retrofit Image Upload dar error
- .debounce () de RxJava interfiriendo con los hilos de mis observables y manejo de errores
- Default Schedulers para rxjava en Android
- Iniciar sesión a través de servicio web de descanso de android utilizando retroalimentación no funciona
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(); } }
- FirebaseAuthInvalidCredentialsException al usar "Una cuenta por dirección de correo electrónico"
- ¿Puede alguien ayudarme con Android RemoteControlClient?