如何对使用CountdownLatch同步的异步代码进行单元测试

时间:2019-03-14 12:39:11

标签: java unit-testing service callback

下面是我要测试的课程: SomeClass.java

public void SomeClass {

    final CountDownLatch latch = new CountDownLatch(1);
    int result;
    registerCallbackWithService(new MyCallback());

    public int callToExternalService(){
        //Do some stuff and make service call
        latch.await();
        return result;
    }

    class MyCallback implements ServiceCallback {
        @Override
        public void onResult(final int res) {
            //do something
            result = res;
            latch.countdown();
        }
    }
}

回调MyCallback在调用callToExternalService()之前已被注册。
如果我编写一个简单的测试来模拟callToExternalService()中进行的服务调用,由于latch.await(),该测试将继续无限运行。
如何在callToExternalService()onResult()中测试逻辑?

1 个答案:

答案 0 :(得分:0)

我通过代码进行了修改,以使用如下受包保护的函数公开正在注册的回调:

const queries = [fn1, fn2, fn3, fn4];

const run = queries.reduceRight((nextQuery, queryFn) => {
    return queryFn.bind(null, nextQuery);
}, function last() {
    console.log("done");
});

run();

现在,为了进行测试,我通过创建一个新的类public void SomeClass { private final CountDownLatch latch = new CountDownLatch(1); private int result; registerCallback(new MyCallback()); public int callToExternalService(){ //Do some stuff and make service call latch.await(); return result; } private class MyCallback implements ServiceCallback { @Override public void onResult(final int res) { //do something result = res; latch.countdown(); } } protected registerCallback(ServiceCallback callback) { registerCallbackWithService(callback); } } 进行测试,并使用该类的实例进行测试。在SomeClassTest extends SomeClass中,我要做的就是覆盖SomeClassTest,以访问正在注册的回调实例。

registerCallback()

现在我只需要使用public class ServiceTest { private ServiceCallback mServiceCallback; class SomeClassTest extends SomeClass { @Override registerCallback(ServiceCallback callback) { mServiceCallback = callback; super.registerCallback(callback); } } } 来执行此操作,就可以根据服务请求调用回调,从而导致在{{1}上的同一doAnswer引用上执行latch.countdown() }}发出服务请求后。

latch