多语言展示
当前在线:399今日阅读:60今日分享:41

在Android Studio中为RxJava和Retrofit单元测试

在开发安卓应用时,很多情况下免不了进行数据请求。这里使用Square公司的开源框架Retrofit这是一个用于 Android 平台的,类型安全的 REST 数据请求框架。而RxJava是由Netflix开发的响应式扩展(Reactive Extensions)的Java实现。本文主要是为了演示在Android Studio中用RxJava和Retrofit进行Http rest api 数据请求的单元测试。
工具/原料

Android Studio 1.4

方法/步骤
2

修改app模块的build.gradle,添加五个依赖项:testCompile 'org.mockito:mockito-core:1.10.19'androidTestCompile 'org.hamcrest:hamcrest-library:1.1'compile 'io.reactivex:rxjava:1.0.+'compile 'io.reactivex:rxandroid:0.23.+'compile 'com.squareup.retrofit:retrofit:1.9.0'

3

在app模块下新添加一个package:"Models",并在其中添加一个Model类:FVideo。其中FVideo.java中的代码如下:package com.lulee007.rxjavarestunittestdemo.Models;import com.google.gson.Gson;/** * User: lulee007@live.com * Date: 2015-12-04 * Time: 11:28 */public class FVideo {    /**     * extra :     * title : 默默点歌台第三期 《开始懂了》56出品微播江湖片段剪辑     * video_type_name : 微播江湖     * video_id : MTAzMTY5MTkw     * video_type : 1     * video_src : http://m.56.com/view/id-MTAzMTY5MTkw.html     * video_duration : 4:30     * play_times : 0     * id : 1864     * icon : http://v1.pfs.56img.com/images/17/9/weibojianghu56i56olo56i56.com_8hd.jpg     */    private String extra;    private String title;    private String video_type_name;    private String video_id;    private int video_type;    private String video_src;    private String video_duration;    private int play_times;    private int id;    private String icon;    public static FVideo objectFromData(String str) {        return new Gson().fromJson(str, FVideo.class);    }    public void setExtra(String extra) {        this.extra = extra;    }    public void setTitle(String title) {        this.title = title;    }    public void setVideo_type_name(String video_type_name) {        this.video_type_name = video_type_name;    }    public void setVideo_id(String video_id) {        this.video_id = video_id;    }    public void setVideo_type(int video_type) {        this.video_type = video_type;    }    public void setVideo_src(String video_src) {        this.video_src = video_src;    }    public void setVideo_duration(String video_duration) {        this.video_duration = video_duration;    }    public void setPlay_times(int play_times) {        this.play_times = play_times;    }    public void setId(int id) {        this.id = id;    }    public void setIcon(String icon) {        this.icon = icon;    }    public String getExtra() {        return extra;    }    public String getTitle() {        return title;    }    public String getVideo_type_name() {        return video_type_name;    }    public String getVideo_id() {        return video_id;    }    public int getVideo_type() {        return video_type;    }    public String getVideo_src() {        return video_src;    }    public String getVideo_duration() {        return video_duration;    }    public int getPlay_times() {        return play_times;    }    public int getId() {        return id;    }    public String getIcon() {        return icon;    }}

4

再在app模块下新添加一个package:"Services",并在其中添加一个Service类:FVideoService。

5

在FVideoService中添加一个 字符串常量:private static  final  String WEB_SERVICE_BASE_URL="xxxx";请把这里的xxxx替换为截图里的真实地址。再添加一个 私有变量FVideoWebService:private  FVideoWebService fVideoWebService;修改FVideoService的默认构造函数,添加如下代码:public FVideoService(){    RequestInterceptor requestInterceptor=new RequestInterceptor() {        @Override        public void intercept(RequestFacade request) {            request.addHeader("Accept","application/json");            request.addHeader("Content-Type","application/json");        }    };    RestAdapter restAdapter=new RestAdapter.Builder()            .setEndpoint(WEB_SERVICE_BASE_URL)            .setLogLevel(RestAdapter.LogLevel.FULL)            .setRequestInterceptor(requestInterceptor)            .build();    fVideoWebService=restAdapter.create(FVideoWebService.class);}在构造函数里首先新建一个请求拦截器RequestInterceptor,设置请求类型和接受类型都为application/json;然后新建一个RestAdapter,设置rest请求url,设置日志,然后把刚才的RequestInterceptor也设置到restAdapter;最后通过restAdapter,create方法把我们之前建的FVideoWebService,建立起来。

6

接下来我们先看看我们的接口json数据:在最外层有一个"msg"和"code",这个是我们这个restapi接口的通用的key,code为0时表示成功,其他情况都是失败,如果失败了,msg会有错误的信息,这时我们通过code来区分请求结果是否正确。具体如下:private class FunnyVideoDataEnvelope{    @SerializedName("code")    private int resultCode;    private String msg;    public Observable filterWebServiceErrors(){        if(resultCode==0){            return Observable.just(this);        }else{            return Observable.error(new Exception(msg));        }    }}为了取得content里面的数据,还需要2个辅助类来帮助。private  class  VideoListDataEnvelope extends  FunnyVideoDataEnvelope{    @SerializedName("content")    private VideoListPage videoListPage;}public class  VideoListPage {    @SerializedName("data")    public  ArrayList videos;    @SerializedName("total_count")    public  int count;}这里让VideoListDataEnvelope继承FunnyVideoDataEnvelope,并新添加一个变量:『   private VideoListPage videoListPage;』其中VideoListPage里包含里两个对象,一个是用来保存视频的总数量,一个是保存当前取得的视频列表。

7

在FVideoService.java中添加一个接口:private  interface  FVideoWebService{    @GET("/videos/type/{type}/page/{page}")    Observable fetchVideo(@Path("type") int type,@Path("page") int page);}这个是基于Retrofit写的请求RestAPI数据的。@GET注解是表示该接口是用Http,Get请求方法;括号中的"/videos/type/{type}/page/{page}"是请求api的部分路径;@Path注解表示这里的参数会对应到请求路径当中其中的{type}和{page}和 注解@Path的type,page对应,这两个参数将在请求的时候替换为请求参数的实际值;返回值是刚才我们封装的对象VideoListDataEnvelope。

8

最后编写取视频数据的接口:public  Observable fetchVideos(int type,int page){    return fVideoWebService.fetchVideo(type, page).flatMap(new Func1>() {        @Override        public Observable call(VideoListDataEnvelope videoListPage) {            return videoListPage.filterWebServiceErrors();        }    }).map(new Func1() {        @Override        public VideoListPage call(VideoListDataEnvelope fVideos) {            return fVideos.videoListPage;        }    });}用RxJava的链式方法,先用flatMap方法过滤code为0的数据,然后在用map方法返回VideoListDataEnvelope里的videoListPage.到此为止我们的Model以及Service都编写完成。

9

现在开始编写测试代码:把光标放到我们的FVideoService上,然后按住『option』+『enter』,选择快捷菜单中的『Create Test』,在弹出来的『Create Test』对话框中,选择『Test Library』JUnit4,然后勾选需要测试的方法『Observable fetchVideos(int type,int page)』

10

这个时候就会在test目录下新建一个『FVideoServiceTest』添加如下代码:FVideoService fVideoService=new FVideoService();Observable videos=fVideoService.fetchVideos(1,0);int size = videos.flatMap(new Func1>() {    @Override    public Observable call(FVideoService.VideoListPage fVideos) {        return Observable.from(fVideos.videos);    }}).count().toBlocking().single();assertThat(size,equalTo(10));首先新建FVideoService,然后获取video,然后通过RxJava的的flatMap取出VideoListPage中的videos,最后取出videos的数量。

11

在测试方法testFetchVideos里右击,然后选择『Run testFetchVideos』执行测试。测试结果如下:All Tests Passed

注意事项

如果有测试操作不对,请参考另一篇的基础篇

推荐信息