java单元测试之如何实现异步接口的测试案例

测试是软件发布的重要环节,单元测试在实际开发中是一种常用的测试方法,java单元测试主要用junit,最新是junit5,本人开发一般用junit4。因为单元测试能够在软件模块组合之前尽快发现问题,所以实际开发中投入产出比很高。实际使用难免会遇到异步操作的接口测试,最常用的情景是别人家的SDK封装了异步处理,需要用测试用例来验证SDK的流程,顺便测试参数的处理情况。由于异步testcase的会在调用后立即返回,异步线程执行完之前test线程已经结束了,无法验证测试最终结果。我们可以通过同步锁方法把异步接口转换为同步处理流程。
一、什么是单元测试?
单元测试是对软件最小实现单元进行的一种测试,例如C语言的函数,C++的类,java的类等。java有一套单元测试框架junit,Android中有AndroidTestCase等等。我们可以用junit对java函数,类,模块接口进行测试。

二、java单元测试教程
对于单元测试的教程网上有好多,这里就不再重复阐述了。
eclipse单元测试
gradle构建junit单元测试教程

三、如何处理异步类型的单元测试
1. 能够获取Thread句柄的异步类型
对于有java thread句柄的测试类型,我们使用使用Thread.join函数等待线程执行完毕。
    @Test
    public void testExplicitThread() {
        System.out.println("testExplicitThread");
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("thread start.");
                try {
                    for (int i = 0; i < 5; i++) {
                        System.out.println("progress: " + i);
                        sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("thread finish.");
                }
            }
        };
        thread.start();
        try {
            thread.join(); // 等待线程执行完毕
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("testExplicitThread exit");
    }
测试用例输出:
testExplicitThread
thread start.
progress: 0
progress: 1
progress: 2
progress: 3
progress: 4
thread finish.
testExplicitThread exit

2. 没有thread句柄的异步单元测试
因为没有thread句柄,所以无法使用join函数。只能手动操作同步锁对异步接口进行同步
Object.wait 当前线程进入等待状态,直到其他线程调用 notify 或者 notifyAll 函数唤醒。
具体实现如下:
    /**
     * 回调接口
     */
    interface Callback {
        void onStart();
        void onProgress(int progress);
        void onFinish();
    }

    /**
     * 异步方法
     */
    static class AsyncDemo {
        private int len = 0;
        private Callback callback = null;
        public AsyncDemo(int len, Callback cb) {
            this.len = len;
            this.callback = cb;
        }

        public void doJob() {
            new Thread() {
                @Override
                public void run() {
                    if (null != callback) {
                        callback.onStart();
                    }
                    try {
                        for (int i = 0; i < len; i++) {
                            if (null != callback) {
                                callback.onProgress(i);
                            }
                            sleep(1000);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        if (null != callback) {
                            callback.onFinish();
                        }
                    }
                }
            }.start();
        }
    }

    private Object mLock = new Object(); // 同步锁
    private int mCount = 0; // 加解锁条件

    @Test
    public void testBlindCallback() {
        System.out.println("testBlindCallback");
        Callback cb = new Callback() {

            public void onStart() {
                System.out.println("onStart");
            }

            public void onProgress(int progress) {
                System.out.println("onProgress: " + progress);
            }

            public void onFinish() {
                System.out.println("onFinish");
                synchronized (mLock) {
                    mCount = 0;
                    mLock.notifyAll(); // 回调执行完毕,唤醒主线程
                }
            }
        };
        System.out.println("before AsyncDemo doJob");
        AsyncDemo demo = new AsyncDemo(5, cb);
        demo.doJob();
        synchronized (mLock) {
            mCount = 1;  // 设置锁条件
            while (mCount > 0) {
                try {
                mLock.wait(); // 等待唤醒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("after AsyncDemo doJob");
    }
测试输出结果:
testBlindCallback
before AsyncDemo doJob
onStart
onProgress: 0
onProgress: 1
onProgress: 2
onProgress: 3
onProgress: 4
onFinish
after AsyncDemo doJob
处理方法就是在测试线程执行异步接口后进入wait,等待回调退出接口(onFinish)唤醒test线程。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值