在单元测试中启动新的JVM

时间:2018-10-10 11:51:01

标签: java locking nio

我有一个可以锁定文件的类。 (请参阅下文。)现在,我有一个单元测试,它断言了同一VM中两个线程之间的成功锁定。但是,实际上我会在两个VM之间使用锁。这就提出了一个问题:我如何在一个单独的进程中启动另一个JVM?

谢谢

Jochen

public class FileLocker {
public static interface StreamAccessor {
    InputStream getInputStream();
    OutputStream getOutputStream();
}
public static void runLocked(File pFile, Consumer<StreamAccessor> pConsumer) {
    Function<StreamAccessor,Object> function = (sa) -> { pConsumer.accept(sa); return null; };
    callLocked(pFile, function);
}
public static <T> T callLocked(File pFile, Function<StreamAccessor,T> pConsumer) {
    try (final RandomAccessFile raf = new RandomAccessFile(pFile, "rw");
            final FileChannel channel = raf .getChannel();
            final FileLock lock = channel.lock()) {
        final StreamAccessor sa = new StreamAccessor() {
            @Override
            public OutputStream getOutputStream() {
                return Channels.newOutputStream(channel);
            }

            @Override
            public InputStream getInputStream() {
                return Channels.newInputStream(channel);
            }
        };
        final T t = pConsumer.apply(sa);
        return t;
    } catch (Throwable thr) {
        throw Exceptions.show(thr);
    }
}

}

1 个答案:

答案 0 :(得分:4)

通过使用 ProcessBuilder ,您可以像在运行其他任何进程一样进行操作。例如,请参见here

您“简单地”必须调用另一个运行Java命令的进程,包括所有必需的命令行选项,等等。棘手的部分可能是确保第二个JVM进程在需要时正确终止。

除此之外:您不应将其称为单元测试。 “ true”单元测试尝试模拟/存根任何此类依赖性。从这个角度来看,您正在尝试进行功能/集成测试。或者,当扭转这种想法时:在单元测试中,您实际上不应使用其他JVM。

最后:明确要测试的内容。您不必自己测试锁定。这是基础操作系统分别为您提供的JVM的功能。验证锁定是否有效没有任何意义。

您应该集中精力进行单元测试,以验证在期望发生这种情况时是否已获得并释放了锁。测试锁定的文件是否已锁定...不是您的职责范围之内的事情(但是对它进行功能测试,只是确保您做对了也不会受到伤害)。