Jim*_*mmy 27 rest android web-services stub dummy-data
我想创建一个Android应用程序,这个应用程序将对Web服务进行RESTful调用以获取一些数据.
我知道RESTful接口会是什么,但我不想要创建自己的实现的麻烦.有没有一种简单的方法来创建一个存根RESTful Web服务,它将返回一些静态数据而无需编写完整的WS应用程序来执行此操作?
如果你想测试实际的HTTP调用代码,我发现使用Sinatra对这类事情非常有用.您可以让端点在几秒钟内返回数据.需要很少的Ruby知识.
require 'sinatra'
require 'json'
get '/Person' do
content_type :json
{ :id => 345, :key2 => 'John Doe' }.to_json
end
Run Code Online (Sandbox Code Playgroud)
你只需要返回一个简单的json对象.
其中一种方法(类似于Vinnie)是在本地实现您的Web服务.例如,您的Web服务允许您在线登录用户并获取用户列表.
webservice接口如下所示:
public interface WebService {
public LoginResponse login(String user, String pass) throws Exception;
public UsersOnlineResponse getOnlineUsers() throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
然后,我们为将在生产中使用的远程web服务实现此接口.远程实现在HTTP客户端的帮助下进行HTTP调用,检索响应并将其解析为适当的响应对象.这是它的一个片段:
public class RemoteWebService implements WebService {
private AndroidHttpClient client = AndroidHttpClient.newInstance(USER_AGENT);
@Override
public LoginResponse login(String user, String pass) throws Exception {
LoginResponse response = client.execute(
createPostRequest(METHOD_LOGIN, user, pass),
new JsonResponseHandler(LoginResponse.class));
handleResponse(response); // verify response, throw exceptions if needed
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
出于测试目的,当webservice不可用或正在开发时,我们实现本地Web服务.本地实现从assets文件夹获取预定义的JSON响应,并将其解析为适当的响应对象.由您决定如何实现Web服务行为:它可以是简单的静态响应或一些随机/验证相关的响应.这是它的一部分:
public class LocalWebService implements WebService {
private Context context;
public LocalWebService(Context context) {
this.context = context;
}
@Override
public LoginResponse login(String user, String pass) throws Exception {
Thread.sleep(DELAY); //emulate network delay
if (validateParams(user, pass)) {
return parseAssetsJson("ws/login.json", LoginResponse.class);
} else {
Response response = parseAssetsJson("ws/status_bad_request.json", Response.class);
throw new WebServiceException(response);
}
}
public <T> T parseAssetsJson(String filename, Class<T> klass) throws IOException {
InputStream is = context.getAssets().open(filename);
return JsonParser.getInstance().fromJson(new InputStreamReader(is), klass);
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们希望无痛地在实现之间切换.webservice的两种实现的使用都是透明的,因为我们使用WebService接口.因此,我们将在应用程序启动时配置WebService实例.应用类适合我们的需求:
public class App extends Application {
public static final boolean USE_LOCAL_WS = false;
private static WebService webService;
public static getWebService() {
return webService;
}
@Override
public void onCreate() {
super.onCreate();
webService = USE_LOCAL_WS ? new LocalWebService(this) : new RemoteWebService();
}
}
Run Code Online (Sandbox Code Playgroud)
最好的办法可能是在开发应用程序代码时为 REST Web 服务创建一个模拟,然后在编写应用程序后将其替换为代码以调用返回“真实”数据的实际 Web 服务。
我目前正在编写一个与您的应用程序非常相似的应用程序,它(像您一样)从 RESTful Web 应用程序获取数据。在我的应用程序中,我遵循GWT 推荐的MVP模式,并且 Martin Fowler 也将其记录为PassiveView模式。
您想要做的是将 REST Web 服务调用的代码抽象为接口(模型)。该模型类的职责是向 Presenter/Controller 提供数据。Presenter 将处理您的所有业务逻辑,然后将数据传递到视图(视图应该非常愚蠢,也允许它被模拟)。在测试期间,您将创建一个 MockModel 来实现模型接口并将测试数据传递给 Presenter - 根本不需要进行实际的 Web 服务调用!然后,当您准备好时,您将用实际的 Web 服务替换此类并开始集成测试。
这种方法还有一个额外的好处,那就是可以轻松地在模拟模型中创建特定的(且可重复的)测试用例。如果您无法控制实际的 Web 服务(我假设您没有),那么这可能很难(甚至不可能)实现。结果应该是一个更健壮、经过更好测试的应用程序,而无需创建任何测试 XML 或 JSON 或自行创建 Web 服务。
| 归档时间: |
|
| 查看次数: |
24385 次 |
| 最近记录: |