Android studio unit test : Issues in writing mock tests for volley request (finished with non-zero exit value 1)
Asked Answered
O

2

1

I have been trying to work on writing test cases for volley custom request, referencing For which I have implemented FakeHttpStack class and FakeRequestQueuefrom here

My project test class structure is as below :

/app
  /src      
  /test
     /java/package/myClassTest.java
     /resources/testfile.txt

Gradle file:

 android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    defaultConfig {        
        minSdkVersion 17
        targetSdkVersion 23
        // Enabling multidex support.
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}
repositories {
    maven { url = "https://oss.sonatype.org/content/repositories/snapshots" }
    jcenter()
}
dependencies {
    compile project(':datetimepickerlibrary')
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'com.google.android.gms:play-services:+'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile files('libs/android-support-v7-recyclerview.jar')
    compile files('libs/ksoap2.jar')
    compile files('libs/nineoldandroids-2.4.0.jar')
    compile files('libs/volley.jar')
    compile 'com.android.support:design:23.0.1'
    testCompile 'junit:junit:4.12'
    testCompile 'org.robolectric:robolectric:3.0'
    testCompile 'org.robolectric:shadows-support-v4:3.0'
    testCompile 'org.robolectric:shadows-httpclient:3.0'
    testCompile 'org.robolectric:shadows-maps:3.0'
    testCompile 'org.mockito:mockito-core:1.+'
    compile 'com.google.guava:guava:16.0.1'
}
task copyResDirectoryToClasses(type: Copy){
    from "${projectDir}/src/test/res"
    into "${buildDir}/intermediates/classes/test/debug/res"
}
assembleDebug.dependsOn(copyResDirectoryToClasses)

My classes are as below:

FakeHttpStack.java

import android.content.Context;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.toolbox.HttpStack;
import com.android.volley.toolbox.StringRequest;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.CharStreams;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class FakeHttpStack implements HttpStack {
   private static final int SIMULATED_DELAY_MS = 500;
   private final Context context;
   FakeHttpStack(Context context) {
    this.context = context;
   }
   @Override
   public HttpResponse performRequest(Request<?> request, Map<String, String> stringStringMap) throws IOException, AuthFailureError {
       try {
        Thread.sleep(SIMULATED_DELAY_MS);
       } catch (InterruptedException e) {}
       HttpResponse response = new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, 200, "OK"));
       List<Header> headers = defaultHeaders();
       response.setHeaders(headers.toArray(new Header[0]));
       //response.setLocale(Locale.JAPAN);
       response.setEntity(createEntity(request));
       return response;
    }
    private List<Header> defaultHeaders() {
       DateFormat dateFormat = new SimpleDateFormat("EEE, dd mmm yyyy HH:mm:ss zzz");
       return Lists.<Header>newArrayList(
            new BasicHeader("Date", dateFormat.format(new Date())),
            new BasicHeader("Server",
                    /* To use the appropriate server information that came back from Sakura server */
                    "Apache/1.3.42 (Unix) mod_ssl/2.8.31 OpenSSL/0.9.8e")
       );
    }
    private HttpEntity createEntity(Request request) throws UnsupportedEncodingException {
        File file = getFileFromPath(this, "res/testfile.txt");
        String resourceName = file.toString();
        System.out.println("resourceName found " +resourceName);        
        if (!file.exists()) {
           System.out.println("No fake file named " + resourceName + " default fake response should be used.");
        } else {
           System.out.println("resourceName found " +file.getName());
           try {
            InputStream stream = context.openFileInput(resourceName);
            String string = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
            if ("randomInt".equals(string)) {
                string = Integer.toString((int) (Math.random() * Integer.MAX_VALUE));
            }
            return new StringEntity(string);
           } catch (IOException e) {
              System.out.println("error reading " + resourceName + e);
            }
        }
        // Since there is no appropriate resources, it returns appropriately
        if (request instanceof StringRequest) {
            return new StringEntity("100");
        }  
        return new StringEntity(" {\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}");
    }
    private static File getFileFromPath(Object obj, String fileName) {
       ClassLoader classLoader = obj.getClass().getClassLoader();
       URL resource = classLoader.getResource(fileName);
       return new File(resource.getPath());
    }
}

FakeRequestQueue.java

import android.content.Context;
import com.android.volley.AuthFailureError;
import com.android.volley.Cache;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.NoCache;
public  class  FakeRequestQueue  extends  RequestQueue {
    public  FakeRequestQueue (Context context) {
        super(new NoCache(), new BasicNetwork(new FakeHttpStack(context)));
        start();
    }
    @Override
    public  void  start () {
        System.out.println("request start");
        super.start();
    }
    @Override
    public  void  stop () {
        System.out.println("request stop");
        super.stop();
    }
    @Override
    public  Cache  getCache () {
        System.out.println("request start");
        return super.getCache();
    }
    @Override
    public  void  cancelAll (RequestFilter filter) {
        System.out.println("Request cancel with filter " + filter);
        super.cancelAll(filter);
    }
    @Override
    public  void  cancelAll (Object tag) {
        System.out.println("Request cancel with tag " + tag);
        super.cancelAll(tag);
    }
    @Override
    public  Request  add (Request request) {
        System.out.println("Note: FakeRequestQueue is used");
        System.out.println("New request "+ request.getUrl()+ " is added with priority "+ request.getPriority());
        try {
            if (request.getBody() == null) {
                System.out.println("body is null");
            } else {
                System.out.println("Body:" + new String(request.getBody()));
            }
        } catch (AuthFailureError e) {
            // cannot do anything
        }
        return super.add(request);
    }
}

myClassTest.java

  public class OppTestCase {
    private static FakeRequestQueue fakeRequestQueue;
    @Before
    public void setup() {
        System.out.println("setup ");
        if (fakeRequestQueue == null) {
            fakeRequestQueue = new FakeRequestQueue(RuntimeEnvironment.application.getApplicationContext());
        }
    }
    @Test
    public void testinglist(){
        GsonRequest<Result> gsonRequest = new GsonRequest<Result>(
                Request.Method.GET,
                Constants.STR_URL_LIST,
                Result.class,
                null,
                new Response.Listener<OpportunityListResult>() {
                    @Override
                    public void onResponse(OpportunityListResult response) {                       
                        System.out.println("response:"+response.toString());
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        assertEquals(volleyError,notNullValue());
                    }
                })
        };
        fakeRequestQueue.add(gsonRequest);
}

My problem is on running the test class it is always giving me error

Error:Gradle: Execution failed for task '::dexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.7.0_21\bin\java.exe'' finished with non-zero exit value 1.

I am new in Android studio and writing test classes please guide where I am going wrong.

Oilskin answered 17/9, 2015 at 5:27 Comment(4)
try running ./gradlew dexDebug --debug to get more information as to why it is failingDeccan
UNEXPECTED TOP-LEVEL ERROR: java.lang.OutOfMemoryError: Java heap spaceError:Execution failed for task '::dexDebug'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.7.0_21\bin\java.exe'' finished with non-zero exit value 3 @DeccanOilskin
I think @Android Weblineindia answer seems to be correct oneDeccan
Does this sort of testing test your code, or volley as a framework?Palmate
A
0

This may happen for many reasons like due to not having enough RAM to build your project, so free up enough memory and if it does not solve your issue then you can try to remove unused dependency libs and sync your gradle, you can refer to here

Alphabetic answered 17/9, 2015 at 6:20 Comment(0)
H
0

In the app-level build.gradle file, add

defaultConfig{
  multiDexEnabled true
}
Hamlet answered 16/10, 2018 at 7:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.