如何对我使用文件锁的java方法进行单元测试?

时间:2014-11-24 16:21:48

标签: java unit-testing locking nio

假设我有以下代码:

public boolean canLock(Path path) throws IOException {
    try(FileChannel byteChannel = FileChannel.open(path);
        FileLock lock = byteChannel.tryLock()) {
        return lock != null;
    }
}

当然这段代码有点无用,只是为了说明问题尽可能紧凑。

现在我想对这个方法进行单元测试:如果文件被另一个进程锁定,我想测试结果为false。有点像这样:

public void canLock_returnsFalse_ifFileIsLocked() {
  // setup
  Path tmpPath = createTmpPath();
  FileLock lock = lock(tmpPath);

  // execution
  boolean actual = canLock(tmpPath);

  // evaluation
  assertFalse(actual);
}

现在出现了问题:documentation说:

  如果由于另一个程序持有重叠锁而无法获取锁,则

[tryLock()]返回null

  

throws OverlappingFileLockException - 如果此Java虚拟机已经拥有与所请求区域重叠的锁,或者此方法中已阻止另一个线程并且正在尝试锁定同一文件的重叠区域

这意味着如果锁是由我自己的进程创建的,那么行为明显不同,因此我的单元测试有问题。如何通过单元测试通常可接受的方式(可移植,可靠,快速,简单)从不同进程创建锁。

2 个答案:

答案 0 :(得分:1)

好像你需要使用JMockit或PowerMock来模拟对FileChannel.open的调用,以便它返回一个模拟的FileChannel。

JMockit mock static method

答案 1 :(得分:0)

考虑到您要测试canLock(...)。在这种情况下,您只需模拟FileChannel。 请参阅Mockito示例:http://www.vogella.com/tutorials/Mockito/article.html

更新: 在上面的场景中,首选使用JMockit(由John B回答),因为需要模拟Mockito中不存在的静态API。但Mockito值得学习:)