开发者

Faking HTTP request responses for testing in Android

I'm writing an Android app which sometimes needs to request data through HTTP from a REST API. I'm using the Apache DefaultHttpClient for performing requests. Is there a way to write tests for this app and "replace" DefaultHttpClient's response when running the tests so that test results are always consistent?

As an example of the things I'd like to test, one of the web services I'm accessing takes a string and performs a text search, returning a paged list of objects. I need to test the cases where the list is empty, the list fits in the first page, or the list is larger than a page and the app needs to make several requests to get the complete list.

I'm not the developer of this web API nor can modify its responses, so I can't change what it returns. For the above example, if I want to test the case where the list returned is empty, I could just search for a string which I'm sure won't return any results, but the other two cases are harder because what the service can return is always changing.

I think ideally I would have a way to get a modified DefaultHttpClient when running tests, that returns a hardcoded result for requests to a given URL instead of actually doing the network request. This way I would always get consistent results independently of the real web service's response.

I'm currently using Robotium for testing but I'm open to using other tools开发者_如何学JAVA too.


Yes, you can definitely "fake" responses when using the HttpClient framework. It's quite convoluted, and I will have to leave most of the details up to you, but I will give you a quick overview:

  1. Implement ClientHttpRequestFactory, mainly so you can override the createRequest() method so you can...

  2. Return your custom implementation of ClientHttpRequest, in which you can override the execute() method so you can ...

  3. Return your custom implementation of ClientHttpResponse in which you will finally be able to return your fake response data, e.g. getBody() can return the content of a file, you can hardcode the headers in getHeaders(), etc.

The rest is figuring out how to best tie all these shenanigans to your service layer.


You might give Charles a try for something like this. Sorta a non-code solution.

http://www.charlesproxy.com/

I use the Charles' reverse proxies and the map local tool for things like this.

What you do is point your request at your local box on the reverse proxy port. Charles in turn can be configured to provide a static hard-coded flat file but to your app it looks like a 100% genuine web service response.

There are lots of other cool things you can do with Charles - watch traffic from your android app to and from your server and breakpoints (which allows you to tweak requests and responses before they are sent and received). Definitely worth checking out.


Another option is to use Dependency Injection so that you can change the HttpClient when running the tests. Check out Guice if you are interested.


I'm guessing you are interested in writing functional tests using the standard Android Junit testing framework. So you could just implement the parts of the API you are using on your own webserver and point at that server when running your tests.

If you'd prefer your tests to be self-contained, you could implement an Http server that runs on the device. Examples of using the Http server available in the Android class library are here and here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜