2016-02-29 6 views
5

In Retrofit 1.x Ho utilizzato il seguente modello per creare classi di servizi API che simulavano una connessione di rete errata per determinate varianti di build.Simula una rete errata con Retrofit 2 (su API effettiva, ovvero non simulata)

// Retrofit 1 
private <T> T create(Class<T> apiServiceClass) { 
    T apiService = restAdapter.create(apiServiceClass); 
    if (!BuildConfig.IS_PRODUCTION_BUILD) { 
     endpoints = mockRestAdapter.create(apiServiceClass, apiService); 
    } 
    return apiService; 
} 

La cosa interessante di questo è che vengono utilizzati i miei endpoint API effettivi. In questo modo posso vedere come si comporta l'applicazione su una connessione traballante e non ho bisogno di fornire risposte burlone/artificiali.

Ora, in Retrofit 2 l'API per MockRestAdapter o meglio MockRetrofit è stata modificata completamente. MockRetrofit#create restituisce ora un BehaviorDelegate. Se provo ad usare lo stesso modello di prima

// Retrofit 2 
private <T> T create(Class<T> apiServiceClass) { 
    T apiService = retrofit.create(apiServiceClass); 
    if (!BuildConfig.IS_PRODUCTION_BUILD) { 
     endpoints = mockRetrofit.create(apiServiceClass).returning(???); 
    } 
    return apiService; 
} 

mi si blocca sulla returning(???). returning prevede un'implementazione Call<?>. Ma non riesco a capire come implementarlo per farlo funzionare come il mio esempio Retrofit 1 (forse non è destinato a).

Quindi la mia domanda è: In generale, come posso ottenere il suddetto pattern Retrofit 1 per simulare una rete errata su un'API effettiva con Retrofit 2?

risposta

6

Alla fine l'ho capito. L'idea è di usare gli intercettori delle applicazioni di OkHttp. Ecco la soluzione.

Innanzitutto, creare un NetworkBehavior.

final NetworkBehavior behavior = NetworkBehavior.create(); 
behavior.setDelay(2000, TimeUnit.MILLISECONDS); 
behavior.setFailurePercent(50); 
behavior.setVariancePercent(50); 

Naturalmente è possibile fornire behavior a un componente di interfaccia utente per modificare dinamicamente questi valori.

Durante la configurazione di OkHttpClient aggiungere il seguente interceptor.

final OkHttpClient.Builder builder = new OkHttpClient.Builder(); 
if (!BuildConfig.IS_PRODUCTION_BUILD) { 
    builder.addInterceptor(new HttpLoggingInterceptor()); 
    builder.addInterceptor(new Interceptor() { 
     @Override public Response intercept(Chain chain) throws IOException { 
      try { 
       Thread.sleep(behavior.calculateDelay(TimeUnit.MILLISECONDS)); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      if (behavior.calculateIsFailure()) { 
       return new Response.Builder() 
         .code(500) 
         .message("MockError") 
         .protocol(Protocol.HTTP_1_1) 
         .request(chain.request()) 
         .body(ResponseBody.create(MediaType.parse("text/plain"), "MockError")) 
         .build(); 
      } 
      return chain.proceed(chain.request()); 
     } 
    }); 
} 

nota che si dovrebbe aggiungere un intercettore di registrazione prima in modo che i registri di richiesta siano correttamente visualizzati. L'oggetto di risposta creato manualmente può naturalmente essere adattato a proprio piacimento. Alcuni valori sono obbligatori (ad esempio o request). Se non li specifichi, riceverai NPE. Lo stesso approccio funzionerebbe anche per il Retrofit 1.

+1

Esattamente quello che cerco. Grazie! – user1795683

+1

Prima di tutto, grazie per aver risposto. Anch'io speravo di risolvere il problema con 'MockRetrofit'. Ho finito per fare qualcosa di simile a te. Ma se stai ruotando tu stesso usando "Interceptor" di OkHttp, potresti anche scrivere la tua classe 'NetworkBehavior' che fa quello che ti serve. Altrimenti, si sta facendo affidamento sull'interna 'retrofit-mock' lib solo per usare due metodi su una classe. La dipendenza – tir38

+0

in build.gradle è 'compile 'com.squareup.retrofit2: retrofit-mock: 2.3.0'' (versione 2.3.0 attualmente) –

Problemi correlati