2013-05-29 14 views
14

Ich versuche, Volley mit Robolectric arbeiten zu lassen. Ich kann sehen, dass meine HTTP-Anfrage aufgerufen wird, und parseNetworkResponse wird aufgerufen (Ich sende eine benutzerdefinierte Unterklasse von JsonRequest), aber mein Listener wird nicht aufgerufen. Irgendein Rat? Hier ist ein Codebeispiel:Robolectric zur Arbeit mit Volley

@Test 
public void testTypeAheadClient() throws Exception { 
    Robolectric.getFakeHttpLayer().interceptHttpRequests(false); 
    //mRemoteRequestQueue and mCustomRequest are set up previously 
    mRemoteRequestQueue.add(mCustomRequest); 
} 

private static class CustomRequest extends JsonRequest<MyObject> { 
    public CustomRequest(String url, 
         Response.Listener<MyObject> listener, 
         Response.ErrorListener errorListener) { 
     super(Request.Method.GET, url, null, listener, errorListener); 
    } 

    @Override 
    protected Response<MyObject> parseNetworkResponse(NetworkResponse response) { 
     System.out.println("in parseNetworkResponse"); 
     try { 
      MyObject myObject = new MyObject(new JSONArray(new String(response.data, "UTF-8"))); 
      return Response.success(myObject, HttpHeaderParser.parseCacheHeaders(response)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return Response.error(new ParseError(e)); 
     } 
    } 
} 
+1

Da Sie Callback verwenden, nehme ich an, dass dies eine asynchrone Bibliothek ist. Um Robolectric mit Android Async Http lib verwenden zu können, müssen Sie einen eigenen Thread-Pool einrichten. Vielleicht kann in diesem Fall die gleiche Lösung gewählt werden. https://groups.google.com/forum/#!msg/robolectric/Z3Yg04gL4hg/iwYlnvHAkO4J – Axxiss

+0

Wenn Sie dies zur Arbeit haben, könnten Sie Ihren gesamten Testcode posten? –

Antwort

19

ich das gleiche Problem gelöst, indem die Request des ResponseDelivery mit einer ersetzt, die nicht den Looper.getMainLooper nicht verwendet(), aber eine neue Executor. Beispielcode:

public static RequestQueue newRequestQueueForTest(final Context context, final OkHttpClient okHttpClient) { 
    final File cacheDir = new File(context.getCacheDir(), "volley"); 

    final Network network = new BasicNetwork(new OkHttpStack(okHttpClient)); 

    final ResponseDelivery responseDelivery = new ExecutorDelivery(Executors.newSingleThreadExecutor()); 

    final RequestQueue queue = 
      new RequestQueue(
        new DiskBasedCache(cacheDir), 
        network, 
        4, 
        responseDelivery); 

    queue.start(); 

    return queue; 
} 

Anmerkung: Mit Robolectric-2.2-SNAPSHOT, die vorherige Version nicht gut spielen mit Volley.

hoffe, das hilft

+0

das funktionierte perfekt, indem es die Callbacks ausführen ließ ... aber jetzt erzeugt es den gefürchteten "Stub!" Ausnahme in dieser Zeile: 'at org.apache.http.ProtocolVersion. (ProtocolVersion.java:5) 'das heißt von:' com.android.volley.toolbox.HurlStack.performRequest (HurlStack.java:108) '' at com.android.volley.toolbox.BasicNetwork.performRequest (BasicNetwork. java: 93) '' at com.android.volley.NetworkDispatcher.run (NetworkDispatcher.java:105) ' – gMale

+1

Wenn Sie die Stub-Ausnahme ProtocolVersion erhalten, bedeutet dies, dass Sie robolectric höher in Ihrem Build-Pfad/pom.xml verschieben müssen . – Gabriel

+0

JA - das war genau das, was ich brauchte. Um die Dinge in einem schönen Paket zu verpacken, können Sie eine nette kleine Volley-Klasse einrichten und sie so starten Volley = neue Volley (RuntimeEnvironment.application, neue ExecutorDelivery (Executors.newSingleThreadExecutor())); – slott

0

Inspiriert von @Thomas Moerman Antwort, habe ich diese Klasse:

public class RealRequestQueue { 

    public static Builder newBuilder() { 
     return new Builder(); 
    } 

    public static final class Builder { 
     private Cache mCache; 
     private Network mNetwork; 

     private Builder() { 
     } 

     public Builder cache(Cache val) { 
      mCache = val; 
      return this; 
     } 

     public Builder network(Network val) { 
      mNetwork = val; 
      return this; 
     } 

     public RequestQueue build() { 
      if (mNetwork == null) mNetwork = new BasicNetwork(new HttpStack() { 
       @Override public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { 
        return null; 
       } 
      }); 
      if (mCache == null) { 
       Context context = RuntimeEnvironment.application.getApplicationContext(); 
       mCache = new DiskBasedCache(new File(context.getCacheDir(), "volley")); 
      } 

      ResponseDelivery responseDelivery = new ExecutorDelivery(Executors.newSingleThreadExecutor()); 
      final RequestQueue queue = new RequestQueue(mCache, mNetwork, 4, responseDelivery); 

      return queue; 
     } 
    } 
} 

ich dann auf der Anforderungswarteschlange auszuspionieren und injizieren sie in das zu testende System

mQueue = spy(RealRequestQueue.newBuilder().network(mNetwork).build());