使用Android-volley进行单元测试
我想知道如何为volley框架创建单元测试。模拟请求和响应,这样我就可以创建不需要Web服务工作和网络访问的单元测试使用Android-volley进行单元测试,android,unit-testing,android-volley,Android,Unit Testing,Android Volley,我想知道如何为volley框架创建单元测试。模拟请求和响应,这样我就可以创建不需要Web服务工作和网络访问的单元测试 我已经在谷歌上搜索过了,但是我没有找到太多关于这个框架的信息我不是100%确定我理解你想要做什么,但是如果我理解了,那么easymock(一个允许创建模拟类的库,你可以调用它并接收预定的响应)将对你有很大帮助。一个叫Lars Vogel的家伙有一篇关于这个话题的好文章,我在不久前使用它时发现它很有用 看看凌空文件夹,在那里你可以找到例子 MockCache.java MockHt
我已经在谷歌上搜索过了,但是我没有找到太多关于这个框架的信息我不是100%确定我理解你想要做什么,但是如果我理解了,那么easymock(一个允许创建模拟类的库,你可以调用它并接收预定的响应)将对你有很大帮助。一个叫Lars Vogel的家伙有一篇关于这个话题的好文章,我在不久前使用它时发现它很有用 看看凌空文件夹,在那里你可以找到例子
MockCache.java
MockHttpClient.java
MockHttpStack.java
MockHttpURLConnection.java
MockNetwork.java
MockRequest.java
MockResponseDelivery.java
我实现了一个名为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;
}
}
这种方法的优点在于,它不需要对代码进行太多更改。测试时,您只需将RequestQueue切换到FakerRequestQueue。因此,它可以用于验收测试或系统测试
另一方面,对于单元测试,可能有更紧凑的方法。例如,您可以将Request.Listener子类实现为单独的类,以便可以轻松测试onResponse方法。我建议您对要测试的内容进行更详细的说明,或者添加一些代码片段。这里有一份@Dmytro提到的
package com.android.volley.mock;
导入com.android.volley.AuthFailureError;
导入com.android.volley.Request;
导入com.android.volley.toolbox.HttpStack;
导入org.apache.http.HttpResponse;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
公共类MockHttpStack实现HttpStack{
私人HttpResponse mrresponsetoreturn;
私有IOException MeException ToThrow;
私有字符串mLastUrl;
私人地图管理员;
私有字节[]mLastPostBody;
公共字符串getLastUrl(){
返回mLastUrl;
}
公共映射getLastHeaders(){
返回mlasheaders;
}
公共字节[]getLastPostBody(){
返回mLastPostBody;
}
public void setResponseToReturn(HttpResponse响应){
mResponseToReturn=响应;
}
public void setExceptionTorRow(IOException异常){
MEExceptionToThrow=异常;
}
@凌驾
公共HttpResponse performRequest(请求、映射附加头)
抛出IOException、AuthFailureError{
if(meExceptionToThrow!=null){
将我的异常抛出;
}
mLastUrl=request.getUrl();
mlasheaders=newhashmap();
if(request.getHeaders()!=null){
mlaseaders.putAll(request.getHeaders());
}
if(additionalHeaders!=null){
mlasheaders.putAll(附加标题);
}
试一试{
mLastPostBody=request.getBody();
}捕获(AuthFailureError e){
mLastPostBody=null;
}
return mResponseToReturn;
}
}
目前我找不到任何文件。但是有大量的样本和谷歌IO 2013视频也很容易被挖掘。对于其他登陆的人,考虑使用OKHTTP而不是截击。这是一个更现代的框架,可以使用OkHttp的MockWebServer更容易地进行测试。如果您使用依赖项注入,您只需注入MyVolley.java而不是默认的Volley.java,这样您的应用程序代码就不需要任何测试更改。您能否指导我如何模拟单元测试Volley请求的响应。您好,我已经实现了fakeRequestQueue,但它没有给出任何响应。看看这里,很好的解决方案。我没有覆盖RequestQueue,但它对我来说仍然很有用。谢谢。
public class FakeRequestQueue extends RequestQueue {
public FakeRequestQueue(Context context) {
super(new NoCache(), new BasicNetwork(new FakeHttpStack(context)));
}
}
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;
}
}