### Question:
PhantomJsInstaller implements Installer { @Override public String install(Archive archive) throws InstallationException { String executable = archive.getPathToExecutable(); File extractTo = new File(outputDirectory, executable); if (!extractTo.exists()) { downloadAndExtract(archive, executable, extractTo); } return extractTo.getAbsolutePath(); } PhantomJsInstaller(Downloader downloader, ArchiveExtractor extractor, File outputDirectory); @Override String install(Archive archive);  }### Answer:
@Test public void shouldDownloadAndExtract() throws Exception { when(downloader.download(archive)).thenReturn(archiveFile); when(archive.getPathToExecutable()).thenReturn(EXTRACT_TO_PATH); assertThat(phantomJsInstaller.install(archive)).isEqualTo(phantomJsBinary.getAbsolutePath()); verify(extractor).extract(same(archiveFile), eq(EXTRACT_TO_PATH), extractToFile.capture()); assertThat(extractToFile.getValue()).isEqualTo(phantomJsBinary); }
@Test public void shouldReturnPreviouslyInstalledPath() throws Exception { phantomJsBinary = temporaryFolder.newFile(EXTRACT_TO_PATH); when(archive.getPathToExecutable()).thenReturn(EXTRACT_TO_PATH); assertThat(phantomJsInstaller.install(archive)).isEqualTo(phantomJsBinary.getAbsolutePath()); verifyNoMoreInteractions(downloader, extractor); }
@Test public void shouldHandleDownloadException() throws Exception { when(archive.getPathToExecutable()).thenReturn(EXTRACT_TO_PATH); when(downloader.download(archive)).thenThrow(new DownloadException("error")); assertThatThrownBy(() -> phantomJsInstaller.install(archive)) .isInstanceOf(InstallationException.class); }
@Test public void shouldHandleExtractionException() throws Exception { when(archive.getPathToExecutable()).thenReturn(EXTRACT_TO_PATH); when(downloader.download(archive)).thenReturn(archiveFile); ExtractionException exception = new ExtractionException("error", new RuntimeException()); doThrow(exception).when(extractor).extract(same(archiveFile), eq(EXTRACT_TO_PATH), any(File.class)); assertThatThrownBy(() -> phantomJsInstaller.install(archive)) .isInstanceOf(InstallationException.class); }