我想知道如何为排球框架创建单元测试。模拟请求,响应,以便我可以创建不需要Web服务工作和网络访问的单元测试。
我用谷歌搜索了它,但我找不到关于该框架的更多信息
答案 0 :(得分:22)
我实现了一个名为 FakeHttpStack 的 HttpStack 的子类,它从res / raw中的本地文件加载伪响应体。我这样做是为了开发目的,即我可以在服务器准备好之前为新API开发一些东西,但是你可以从这里学到一些东西(例如,覆盖HttpStack#peformRequest和createEntity)。
/**
* Fake {@link HttpStack} that returns the fake content using resource file in res/raw.
*/
class FakeHttpStack implements HttpStack {
private static final String DEFAULT_STRING_RESPONSE = "Hello";
private static final String DEFAULT_JSON_RESPONSE = " {\"a\":1,\"b\":2,\"c\":3}";
private static final String URL_PREFIX = "http://example.com/";
private static final String LOGGER_TAG = "STACK_OVER_FLOW";
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",
/* Data below is header info of my server */
"Apache/1.3.42 (Unix) mod_ssl/2.8.31 OpenSSL/0.9.8e")
);
}
/**
* returns the fake content using resource file in res/raw. fake_res_foo.txt is used for
* request to http://example.com/foo
*/
private HttpEntity createEntity(Request request) throws UnsupportedEncodingException {
String resourceName = constructFakeResponseFileName(request);
int resourceId = context.getResources().getIdentifier(
resourceName, "raw", context.getApplicationContext().getPackageName());
if (resourceId == 0) {
Log.w(LOGGER_TAG, "No fake file named " + resourceName
+ " found. default fake response should be used.");
} else {
InputStream stream = context.getResources().openRawResource(resourceId);
try {
String string = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
return new StringEntity(string);
} catch (IOException e) {
Log.e(LOGGER_TAG, "error reading " + resourceName, e);
}
}
// Return default value since no fake file exists for given URL.
if (request instanceof StringRequest) {
return new StringEntity(DEFAULT_STRING_RESPONSE);
}
return new StringEntity(DEFAULT_JSON_RESPONSE);
}
/**
* Map request URL to fake file name
*/
private String constructFakeResponseFileName(Request request) {
String reqUrl = request.getUrl();
String apiName = reqUrl.substring(URL_PREFIX.length());
return "fake_res_" + apiName;
}
}
要使用FakeHttpStack,您只需将其传递给 RequestQueue 即可。我也覆盖了RequestQueue。
public class FakeRequestQueue extends RequestQueue {
public FakeRequestQueue(Context context) {
super(new NoCache(), new BasicNetwork(new FakeHttpStack(context)));
}
}
这种方法的好处在于,它不需要对代码进行太多更改。您只需在测试时将 RequestQueue 切换为 FakeRequestQueue 。因此,它可以用于验收测试或系统测试。
另一方面,对于单元测试,可能会有更紧凑的方式。例如,您可以将 Request.Listener 子类实现为单独的类,以便可以轻松地测试onResponse方法。我建议你详细说明你想要测试的内容或者放一些代码片段。
答案 1 :(得分:8)
看一下volley tests文件夹,你可以在那里找到例子。
MockCache.java
MockHttpClient.java
MockHttpStack.java
MockHttpURLConnection.java
MockNetwork.java
MockRequest.java
MockResponseDelivery.java
答案 2 :(得分:0)
不是100%确定我理解你想做什么,但如果我这样做,那么easymock(一个允许创建模拟类的lib,你可以调用并接收预定的响应)将帮助你许多。一个名叫Lars Vogel的人有一篇关于这个话题的好文章,我发现它在我使用它的时候有用了。
答案 3 :(得分:0)
以下是@Dmytro提到的the current volley's MockHttpStack副本
package com.android.volley.mock; import com.android.volley.AuthFailureError; import com.android.volley.Request; import com.android.volley.toolbox.HttpStack; import org.apache.http.HttpResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class MockHttpStack implements HttpStack { private HttpResponse mResponseToReturn; private IOException mExceptionToThrow; private String mLastUrl; private Map<String, String> mLastHeaders; private byte[] mLastPostBody; public String getLastUrl() { return mLastUrl; } public Map<String, String> getLastHeaders() { return mLastHeaders; } public byte[] getLastPostBody() { return mLastPostBody; } public void setResponseToReturn(HttpResponse response) { mResponseToReturn = response; } public void setExceptionToThrow(IOException exception) { mExceptionToThrow = exception; } @Override public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError { if (mExceptionToThrow != null) { throw mExceptionToThrow; } mLastUrl = request.getUrl(); mLastHeaders = new HashMap<String, String>(); if (request.getHeaders() != null) { mLastHeaders.putAll(request.getHeaders()); } if (additionalHeaders != null) { mLastHeaders.putAll(additionalHeaders); } try { mLastPostBody = request.getBody(); } catch (AuthFailureError e) { mLastPostBody = null; } return mResponseToReturn; } }