Android studio unit test:为抽插请求编写模拟测试的问题(以非零退出值1结束)

时间:2015-09-17 05:27:07

标签: java android unit-testing android-volley

我一直在尝试编写针对齐射自定义请求的测试用例,引用我已经实现了FakeHttpStack类和来自here FakeRequestQueue

我的项目测试类结构如下:

/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)

我的课程如下:

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);
}
     

我的问题正在运行测试类,它总是给我错误

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.

我是Android工作室的新手,编写测试课程,请指导我出错的地方。

2 个答案:

答案 0 :(得分:0)

这可能由于许多原因而发生,例如由于没有足够的RAM来构建项目,因此释放足够的内存,如果它无法解决您的问题,那么您可以尝试删除未使用的依赖库并同步您的gradle,您可以参考here

答案 1 :(得分:0)

在应用程序级别的build.gradle文件中,添加

defaultConfig{
  multiDexEnabled true
}