javajuniper

How to test an ExecutorService thrown RuntimeException


I'm trying to test a service method that throws a runtimeexception in a executorservice ran job. However the test doesn't seem to be catching it. I suppose because the test finishes before the executor job is finished. What is the trick to find a solution, synchronize the test or something ?

The service method

public void migrateSplitFile(String runtimeWorkspace, File jobFile, File errorFile, String inputFile) {
    ExecutorService executorService = Executors.newFixedThreadPool(maxImportJobs);
    executorService.execute(()->{
        try {
            importSingleFile(runtimeWorkspace, jobFile, errorFile, inputFile);
        } catch (IOException e) {
            throw new RuntimeException("Failed running import for file [" + inputFile + "]", e);
        }
    });
}

private void importSingleFile(String runtimeWorkspace, File jobFile, File errorFile, String inputFile) throws IOException {
    Optional<RunningJob> jobResult = importJobManager.executeImport(inputFile, runtimeWorkspace);
    if (jobResult.isPresent()) {
        RunningJob job = jobResult.get();
        fileUtils.writeStringToFile(jobFile, "Ran job [" + job.getJobId() + "] for input file [" + inputFile + "]");
    } else {
        fileUtils.writeStringToFile(errorFile, "input file [" + inputFile + "] failed to process");
    }
}

The test

@Test
void migrateSplitFileRuntimeException() {
    assertThrows(RuntimeException.class,
            () -> {
                String runtimeWorkspace = "./test";

                File testDir = new File(runtimeWorkspace + "/inputfiles");
                FileUtils.forceMkdir(testDir);
                File fakeInputFile = new File(runtimeWorkspace + "/inputfiles/test.txt");
                FileUtils.writeStringToFile(fakeInputFile, "test", "UTF-8", true);

                String inputFile = ".\\test\\inputfiles\\test.txt";

                File jobFile = new File(runtimeWorkspace + "/jobs.txt");
                File errorfile = new File(runtimeWorkspace + "/errors.txt");

                Mockito.doThrow(new Auth0Exception("")).when(importJobManager).executeImport(inputFile, runtimeWorkspace);

                auth0EngineService.migrateSplitFile(runtimeWorkspace, jobFile, errorfile, inputFile);

                FileUtils.deleteDirectory(new File(runtimeWorkspace));
            });
}

I'm open for any suggestions, before I implemented the executorservice my test was working


Solution

  • You can use:

    Future<?> f = executorService.submit(()->{
        try {
            importSingleFile(runtimeWorkspace, jobFile, errorFile, inputFile);
        } catch (IOException e) {
            throw new RuntimeException("Failed running import for file [" + inputFile + "]", e);
        }
    });
    

    Then afterwards use:

    f.get();
    

    That will throw any runtime exceptions that occurred during the execution of the task. It will also block until the task has completed.