使用Robolectric模拟Http请求和响应

8 4月

习惯了用Gradle管理依赖以后突然回到Android开发,才发现Idea 12 对Android-Gradle项目支持很烂,只有手动下载依赖。

Android App的开发比普通Java Web或者Java Application开发麻烦很多。主要是集成测试使用的Instrumented Test必须在模拟器或者真机上测试,挺耽误时间的。
这样的测试通常粒度较大,测试的编写和维护较为困难,而最为重要的是,由于速度慢,如果使用TDD来进行开发,根本无法达到快速开发的要求。

所以在Android开发中,尽可能多使用单元测试保证每个模块的正确性,来尽可能保证集成测试的成功率。

 

基于Mockito的简单测试

Android SDK也有测试框架,但是那个不是基于普通JVM的,运行起来还是需要模拟器或者真机。要基于普通JVM测试,就必须让模块尽可能的不依赖于Android的东西,需要依赖的也用Mockito等Mock掉。

如果需要Mock的是自己的代码还好,如果是Android的东西,还需要处理各种状态和返回量。

比如我们的APP需要调用WifiManager,如果只是检测Wifi是否开启还比较方便,只需要mock以后设定when就行了。


如果我们需要扫描Wifi,然后检测Wifi状态等,工作就变动了。你需要仔细思考Android设备正常情况下的状态变动,还需要构造哦一个List<ScanResult>


其实以上问题还好,因为我们mock出了WifiManager以后将它传入调用的类就行了。


但是我现在做的应用需要访问网络内容,使用的DefaultHttpClient,它是写在业务代码里面的,虽然也可以解耦合做和wifimanager同样的处理,但是着既不合理也不方便。

Robolectric

虽然可以使用mockito这类框架来mock掉一部分依赖,但是由于Android平台自身的复杂性,mock的正确性很难保证。

而Robolectric是一个单元测试框架,它提供了一个测试用的Android模拟,目前只提供了android-base-4.1.2_r1_rc,但是足够使用了。一方面它运行于普通JVM,保证了速度,另一方面,它模拟了绝大部分繁琐的功能,比如布局解析,资源处理。

这样就可以像对待黑箱测试一样的编写测试,集中精力在业务处理上,而不是Android的实现上。

Robolectric模拟Http请求和响应

Robolectric提供了一个虚假的Http层,你可以拦截正常的请求,用另外一个替换掉;也可以不拦截真实请求,使用真的Http层。

当然单元测试中尽可能不依赖外界,所以一般都拦截并替换掉。

如果逻辑简单,可以直接使用setDefaultHttpResponse设定Http层返回的结果,这样所有的请求都是同样的响应。


如果你需要按照顺序进行多个响应,可以使用addPendingHTTPResponse,以此添加你需要的响应。


通过addPendingHTTPResponse方法添加的响应会进入队列中,如果需要清空可以使用clearPendingHTTPResponses

通过规则模拟HTTP请求和响应

上面的方法都比较简单,如果处理的情况比较复杂,需要判断HTTP头和参数,或者希望HTTP层可以灵活处理各种情况,可以使用addHTTPResponseRule

最常见的判断是网址


这样如果访问sucessfullcall就会返回一个200响应,内容为”response body”,如果访问failedcall会返回400响应。

动态模拟HTTP请求和响应

如果还有复杂的参数,或者需要区分method等等,还可以实现ResponseRule接口,在matches中判断是否响应,在getResponse中判断是否响应。最后通过addHttpResponseRule添加。


参考

Robolectric

发表评论

电子邮件地址不会被公开。