Launch a new JVM in a unit test

user1774051 :

I've got a class, which is locking files. (See below.) Now, I've got a unit test, which asserts the successful locking between two threads in the same VM. However, I'd actually have the locks working between two VM's. Which brings up the question: How would I lauch another JVM in a separate process?

Thanks,

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);
    }
}

}

GhostCat salutes Monica C. :

You do that like you are running any other process, by using a ProcessBuilder. See here for example.

You "simply" have to invoke another process that runs your java command, including all the required command line options and so on. The tricky part might be ensure that the second JVM process terminates correctly when you want it to.

Beyond that: you shouldn't call it a unit test then. A "true" unit test tries to mock/stub any such dependency. From that point of view, you are trying to do a functional/integration test. Or, when reversing that thought: in a unit test, your really should not use different JVMs.

Finally: be clear about what you intend to test. You don't have to test locking itself. That is a feature that the JVM respectively the underlying operating system provides to you. There is no point in verifying that locking works.

You should focus your unit test to verify that locks are acquired and released when you expect that to happen. Testing that a locked file is locked ... isn't something that lies within your responsibility (but having a functional test for that, just to make sure you got it right doesn't hurt either).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=93496&siteId=1