APP开发实战176-服务器接口的单元测试

来源:互联网 发布:江苏电信网络测速 编辑:程序博客网 时间:2024/06/17 11:49

31.19 服务器接口的单元测试

在APP开发中,往往接口开发和APP开发的进度是并行的,甚至还落后于APP开发,导致在APP端调试接口非常麻烦,如果在APP端能模拟接口调用,那就极大的提高了APP开发和测试的效率。

31.19.1 单元测试简介

用Android Studio新建工程后,在app的java文件夹中,通常会包含如下三个文件夹:一个是app实际运行使用的代码文件夹,另两个就是单元测试代码的文件夹。如下图所示:

这两个单元测试文件夹:一个是供androidTest用的,这类单元测试代码只能在Android设备或模拟器上进行;一个是供test用的,这类单元测试代码可以直接在电脑上运行,不需要连接模拟器和Android设备。

想要运行单元测试代码,则鼠标选中ApplicationTest或ExampleUnitTest文件,点击鼠标左键,在可以看到Run ‘ApplicationTest’或Run ‘ExampleUnitTest’的菜单,点击就可以运行androidTest或test单元测试的代码了。

31.19.2 使用MockWebServer进行接口的单元测试

    Square提供了一个能够模拟接口调用的工具MockWebServer,可以很方便的集成在APP中,进行接口相关功能的测试。

    下面就以使用的比较多的volley+okhttp 这种网络库的组合方式为例,说明MockWebServer的使用。

    首先需要在工程中集成MockWebServer库文件。

    AndroidStudio默认有两种单元测试:androidTest和test,那么在gradle中集成单元测试的库,也有两种方式:

//供androidTest用

androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.6.0'

//供test用

testCompile 'com.squareup.okhttp3:mockwebserver:3.6.0'

    mockwebserver库的版本号最好与okhttp库的版本号一致,否则可能会编译出错。

    如果APP和服务器交互使用的是json格式的数据,那运行test单元测试代码时,还需在工程中集成json.jar文件:

testCompile files('libs/json.jar')

    否则会运行出错。

    如果运行AndroidTest单元测试代码,则不需要集成json.jar文件。

 

模拟调用登录接口的具体代码如下:

public class ApplicationTest extends ApplicationTestCase<Application>{

    final String TAG = "ApplicationTest";

    //定义接口返回的Json字符串
    String strJson = "{\"status\":\"success\"}";

    final BlockingQueue<Object> queue= new ArrayBlockingQueue<>(2);

    //创建MockWebServer对象
    MockWebServer server = new MockWebServer();

    public ApplicationTest() {
        super(Application.class);
    }

    @Test
    public void testLogin() throws Exception{
       

        // 设置接口返回的状态码、头字段的内容和Body体的内容
        MockResponse response = new MockResponse()
                .setResponseCode(200)
                .addHeader("Content-Type","application/json;charset=UTF-8")
                .setBody(strJson);

    //利用throttleBody函数可以模拟弱网状态,当前设置每秒传输512个字节的数据
        response.throttleBody(512, 1,TimeUnit.SECONDS);

        server.enqueue(response);

        // 启动server
        server.start();

        login("admin", "123456");
    }

    public void login(String userName,String password){

        JSONObject jsonObject = new JSONObject();

        try {
            jsonObject.put("jsonrpc","2.0");
            jsonObject.put("method","call");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        JSONObject params = new JSONObject();

        try {
            params.put("app_version","0.6.0");
            params.put("login",userName);
            params.put("password",password);

            jsonObject.put("params",params);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {

           //获取请求URL,不能使用普通的URL,一定要使用server.url()返回的 URL,不然没法连接Mock服务器
            String pathUrl = server.url(Urls.LOGIN).toString();
            Log.v(TAG, "url: " +pathUrl);

            request(pathUrl, jsonObject,UserInfo.class);
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void request(String url,JSONObject jsonObject, final Class<?> type) throws Exception {
        NetworkManager.getInstance(EamApplication.getContext()).JsonRequest(TAG,url, jsonObject,
                new Response.Listener<JSONObject>(){
                    @Override
                    public void onResponse(JSONObjectjsonObject) {

                    Log.v(TAG, "responsejson对象: " +jsonObject.toString());

                   //volley库用到异步的回调,在此使用BlockingQueue来等待服务器的返回结果,然后验证结果

                    queue.add(jsonObject.toString());

                    parseToResponse(jsonObject,type);

                    }
                }, new Response.ErrorListener(){
                    @Override
                    public void onErrorResponse(VolleyErrorerror) {
                        Log.e(TAG,error.getMessage(), error);
                    }
                });

        //获取发送的请求数据
        RecordedRequest request = server.takeRequest();

        assertEquals("POST",request.getMethod());

        Log.v(TAG, "path: " +request.getPath());

        Log.v(TAG, "body: " +request.getBody().toString());

       //验证服务器的返回结果是否和预期结果一致
        Object obj = queue.take();
        if (obj instanceof String) {

            Log.v(TAG, "queue json对象: " + obj.toString());

            assertEquals(strJson,obj.toString());
        }

        //关闭server
        server.shutdown();
    }
}