在使用square retrofit framework时,模拟服务器进行测试的最佳方式是什么?
可能的方式:
作为响应返回,将这个带注释的接口作为模拟类使用,并使用RestAdapter.create()提供的版本(不会测试gson json
理想情况下,我希望被模拟的服务器提供json响应,这样我就可以同时测试gson序列化。
任何例子都会非常感谢。
发布于 2013-07-11 18:04:50
我决定尝试方法1,如下所示
public class MockClient implements Client {
@Override
public Response execute(Request request) throws IOException {
Uri uri = Uri.parse(request.getUrl());
Log.d("MOCK SERVER", "fetching uri: " + uri.toString());
String responseString = "";
if(uri.getPath().equals("/path/of/interest")) {
responseString = "JSON STRING HERE";
} else {
responseString = "OTHER JSON RESPONSE STRING";
}
return new Response(request.getUrl(), 200, "nothing", Collections.EMPTY_LIST, new TypedByteArray("application/json", responseString.getBytes()));
}
}并通过以下方式使用它:
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setClient(new MockClient());它工作得很好,允许您测试json字符串,而不必联系真正的服务器!
发布于 2015-12-20 05:06:36
Mock Retrofit 2.0测试请求
由于旧的机制,如创建MockClient类并从Client实现它,在Retrofit 2.0中不再起作用,这里我描述了一种新的方法来做到这一点。您现在需要做的就是为添加OkHttpClient的自定义拦截器,如下面的所示。FakeInterceptor类只是覆盖了intercept方法,如果应用程序处于DEBUG模式,则返回给定的JSON。
RestClient.java
public final class RestClient {
private static IRestService mRestService = null;
public static IRestService getClient() {
if(mRestService == null) {
final OkHttpClient client = new OkHttpClient();
// ***YOUR CUSTOM INTERCEPTOR GOES HERE***
client.interceptors().add(new FakeInterceptor());
final Retrofit retrofit = new Retrofit.Builder()
// Using custom Jackson Converter to parse JSON
// Add dependencies:
// com.squareup.retrofit:converter-jackson:2.0.0-beta2
.addConverterFactory(JacksonConverterFactory.create())
// Endpoint
.baseUrl(IRestService.ENDPOINT)
.client(client)
.build();
mRestService = retrofit.create(IRestService.class);
}
return mRestService;
}
}IRestService.java
public interface IRestService {
String ENDPOINT = "http://www.vavian.com/";
@GET("/")
Call<Teacher> getTeacherById(@Query("id") final String id);
}FakeInterceptor.java
public class FakeInterceptor implements Interceptor {
// FAKE RESPONSES.
private final static String TEACHER_ID_1 = "{\"id\":1,\"age\":28,\"name\":\"Victor Apoyan\"}";
private final static String TEACHER_ID_2 = "{\"id\":1,\"age\":16,\"name\":\"Tovmas Apoyan\"}";
@Override
public Response intercept(Chain chain) throws IOException {
Response response = null;
if(BuildConfig.DEBUG) {
String responseString;
// Get Request URI.
final URI uri = chain.request().url().uri();
// Get Query String.
final String query = uri.getQuery();
// Parse the Query String.
final String[] parsedQuery = query.split("=");
if(parsedQuery[0].equalsIgnoreCase("id") && parsedQuery[1].equalsIgnoreCase("1")) {
responseString = TEACHER_ID_1;
}
else if(parsedQuery[0].equalsIgnoreCase("id") && parsedQuery[1].equalsIgnoreCase("2")){
responseString = TEACHER_ID_2;
}
else {
responseString = "";
}
response = new Response.Builder()
.code(200)
.message(responseString)
.request(chain.request())
.protocol(Protocol.HTTP_1_0)
.body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()))
.addHeader("content-type", "application/json")
.build();
}
else {
response = chain.proceed(chain.request());
}
return response;
}
}基于GitHub的项目源代码
发布于 2013-10-15 12:29:23
测试对您的对象的JSON反序列化(假设使用TypeAdapters?)这似乎是一个单独的问题,需要单独的单元测试。
我个人使用版本2。它提供了类型安全、重构友好的代码,可以很容易地进行调试和更改。毕竟,如果您不是为了测试而创建API的替代版本,那么将API声明为接口又有什么好处呢!win的多态。
另一种选择是使用Java Proxy。这实际上是Retrofit (目前)实现其底层HTTP交互的方式。无可否认,这将需要更多的工作,但将允许更多的动态模拟。
https://stackoverflow.com/questions/17544751
复制相似问题