0

我有异步方法,我使用 DeferredResult 作为返回类型。我想为那个方法编写junit测试,我在循环中调用这个方法,例如100次,我需要测量每次调用该方法的执行时间。

这是方法示例:

@Transactional(readOnly = true)
@Override
public DeferredResult foo() {
    DeferredResult dr = new DeferredResult(5000L, "timeout");
    dr.onCompletion(() -> {
        // do some stuff
    });
    deferredResults.add(dr);

    return dr;        
}

创建了 deferredResult 我添加到集合中,并在另一个方法中迭代该集合,在该方法中设置了一些结果,然后返回 dr。

你能告诉我应该如何测试我将能够测量该方法的多次调用的执行时间吗?

@Test
public void executionTimeTest() {
    for (int i = 0; i < 100; i++) {
        asyncService.foo();
    }

    // here I need get execution time for each call
}

谢谢。

4

1 回答 1

0

我认为解决这个问题的最好方法是在Spring docs推荐的 DeferredResult 类中添加额外的数据。准确地说,spring docs 中的以下句子指出了这种可能性。

子类可以扩展此类以轻松地将附加数据或行为与 DeferredResult 关联。例如,可能希望通过扩展类并为用户添加一个附加属性来关联用于创建 DeferredResult 的用户。这样,以后可以很容易地访问用户,而无需使用数据结构来进行映射。

鉴于这种可能性,您可以扩展 DeferredResult 并添加开始和结束时间:

public class MyDeferredResult extends DeferredResult {

    long startTime;
    long endTime;

    public MyDeferredResult(Long timeout, Object timeoutResult) {
        super(timeout, timeoutResult);
        this.startTime = System.currentTimeMillis();
    }

    @Override
    public boolean setResult(Object result) {
        boolean r = super.setResult(result);
        this.endTime = System.currentTimeMillis();
        return r;
    }

    public long totalTime() {
        return (endTime - startTime)/1000;
    }

}

然后,您的 Async Service 可以与此类似:

 public MyDeferredResult foo() {
    MyDeferredResult dr = new MyDeferredResult(5000L, "timeout");
    new Thread(() -> {
        Random r = new Random();
        System.out.println("async task started");
        try {
            Thread.sleep(r.nextInt(4) * 1000 );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("async task finished");
        dr.setResult("test async result");
    }).start();
    deferredResults.add(dr);
    return dr;
}

boolean hasResults() {
    boolean result = true;
    for(MyDeferredResult dr: deferredResults) {
        result = result && dr.hasResult();
    }
    return result;
}

最后,在您的测试中,您可以检索每次执行的总时间:

   @Test
    public void executionTimeTest() {
        Service service = new Service();
        for (int i = 0; i < 10; i++) {
            service.foo();
        }

       while (!service.hasResults()) {
            System.out.println("No result yet");
       }

        for(MyDeferredResult dr: service.deferredResults) {
            System.out.println(dr.totalTime());
        }
    }
于 2018-05-31T22:43:33.123 回答