如何在Java中测试IO问题?

时间:2012-06-04 15:29:29

标签: java unit-testing io

如果不使用休眠的模拟流(因为它们会对中断做出反应),如何测试我的应用程序代码的行为是否存在非常糟糕的IO性能?

例如,我想测试一个ConcurrentWrapper实用程序,该实用程序具有文件IO的线程池。它将每个操作提交到ExecutorService invokeAll()并超时。我想确认不仅是ConcurrentWrapper的调用在超时之前退出,而且它还以某种方式使其内部ExecutorService的线程终止(以避免泄漏)。

我需要以某种方式模拟内部线程中的缓慢IO,但是会忽略中断(就像真正的IO一样)。

稍微澄清:没有像“睡觉和吞下InterruptedException”或“睡觉,抓住InterruptedException并重新入睡”这样的答案是可以接受的。我想测试我的代码如何处理中断,这样的检测会通过自己处理它们来破坏目的。

3 个答案:

答案 0 :(得分:1)

你可以以一种坚持通过中断睡觉的方式睡觉:

long start = System.currentTimeMillis();
long end = start + sleepTime;
for (long now = start; now < end; now = System.currentTimeMillis()) {
    try {
        Thread.sleep(end - now);
    } catch (InterruptedException ignored) {
    }
}

答案 1 :(得分:0)

对于超时测试,您实际上可以花费最长时间来执行测试,在JUnit中您可以包含注释超时:

@Test(timeout=100)
public void method_withTimeout() {
       while(true);
}

对于该方法退出的测试部分,您可以使用提供超时的Future接口来获取结果。

答案 2 :(得分:0)

如果我理解你的问题,ReentrantLock可能会有所帮助。

final ReentrantLock lock = new ReentrantLock();

Callable<Void> c = new Callable<Void>() {
  public void call() {
    lock.lock();

    try {

       if (Thread.currentThread().isInterrupted()) {
         ...
       }
    }
    finally {
      lock.unlock();
    }
  }
}

// Submit to the pool
Future<Void> future = executorService.submit(c);

// you might want to sleep a bit to give the pool a chance
// to pull off the queue.

// Issue a cancel
future.cancel();

// Now release the lock, which should let your
// callable continue onto to the interrupted check.
lock.unlock();

请注意,“lock”方法不会抛出任何InterruptedException(虽然有一个名为“lockInterruptibly”的方法),如果你查看该类的代码,它就不会被捕获和吞咽(就像你一样)陈述不是你想要的。)