@Test
public void testLogLocalDirectoryContents() throws Exception
{

    String appenderName = "TestWriterAppender";
    StringWriter stringWriter = addLoggingWriterAppender(appenderName);
    LogLevel originalLevel = getLogLevel(DownloaderController.class);
    setLogLevel(DownloaderController.class, LogLevel.INFO);
    /*
     * Create and inject mock objects
     */
    DownloaderWebClient mockDownloaderWebClient = mock(DownloaderWebClient.class);
    DownloaderWebClient originalDownloaderWebClient = (DownloaderWebClient) ReflectionTestUtils.getField(downloaderController, "downloaderWebClient");
    ReflectionTestUtils.setField(downloaderController, "downloaderWebClient", mockDownloaderWebClient);
    DownloaderManifestReader mockDownloaderManifestReader = mock(DownloaderManifestReader.class);
    DownloaderManifestReader originalDownloaderManifestReader =
        (DownloaderManifestReader) ReflectionTestUtils.getField(downloaderController, "manifestReader");
    ReflectionTestUtils.setField(downloaderController, "manifestReader", mockDownloaderManifestReader);
    BusinessObjectDataHelper mockBusinessObjectDataHelper = mock(BusinessObjectDataHelper.class);
    BusinessObjectDataHelper originalBusinessObjectDataHelper =
        (BusinessObjectDataHelper) ReflectionTestUtils.getField(downloaderController, "businessObjectDataHelper");
    ReflectionTestUtils.setField(downloaderController, "businessObjectDataHelper", mockBusinessObjectDataHelper);
    S3Service mockS3Service = mock(S3Service.class);
    S3Service originalS3Service = (S3Service) ReflectionTestUtils.getField(downloaderController, "s3Service");
    ReflectionTestUtils.setField(downloaderController, "s3Service", mockS3Service);
    StorageFileHelper mockStorageFileHelper = mock(StorageFileHelper.class);
    StorageFileHelper originalStorageFileHelper = (StorageFileHelper) ReflectionTestUtils.getField(downloaderController, "storageFileHelper");
    ReflectionTestUtils.setField(downloaderController, "storageFileHelper", mockStorageFileHelper);
    StorageHelper mockStorageHelper = mock(StorageHelper.class);
    StorageHelper originalStorageHelper = (StorageHelper) ReflectionTestUtils.getField(downloaderController, "storageHelper");
    ReflectionTestUtils.setField(downloaderController, "storageHelper", mockStorageHelper);
    /*
     * Start test
     */
    Path localPath = Files.createTempDirectory(null);
    try
    {
        String s3KeyPrefix = "s3KeyPrefix";
        String storageName = "S3_MANAGED";
        Path targetDirectoryPath = localPath.resolve(s3KeyPrefix);
        Path targetFilePath = targetDirectoryPath.resolve("file");
        DownloaderInputManifestDto downloaderInputManifestDto = new DownloaderInputManifestDto();
        BusinessObjectData businessObjectData = new BusinessObjectData();
        StorageUnit storageUnit = new StorageUnit(new Storage(storageName, null, null), null, null, StorageUnitStatusEntity.ENABLED, null, null, null);
        S3KeyPrefixInformation s3KeyPrefixInformation = new S3KeyPrefixInformation();
        s3KeyPrefixInformation.setS3KeyPrefix(s3KeyPrefix);
        /*
         * Mock operations on mocked dependencies
         */
        when(mockDownloaderManifestReader.readJsonManifest(any())).thenReturn(downloaderInputManifestDto);
        when(mockDownloaderWebClient.getBusinessObjectData(any())).thenReturn(businessObjectData);
        when(mockBusinessObjectDataHelper.getStorageUnitByStorageName(any(), any())).thenReturn(storageUnit);
        when(mockDownloaderWebClient.getS3KeyPrefix(any())).thenReturn(s3KeyPrefixInformation);
        when(mockS3Service.downloadDirectory(any())).then(new Answer<S3FileTransferResultsDto>()
        {
            @Override
            public S3FileTransferResultsDto answer(InvocationOnMock invocation) throws Throwable
            {
                Files.createFile(targetFilePath);
                return null;
            }
        });
        /*
         * Make the call to the method under test
         */
        RegServerAccessParamsDto regServerAccessParamsDto = null;
        File manifestPath = null;
        S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = new S3FileTransferRequestParamsDto();
        s3FileTransferRequestParamsDto.setLocalPath(localPath.toString());
        s3FileTransferRequestParamsDto.setMaxThreads(1);
        downloaderController.performDownload(regServerAccessParamsDto, manifestPath, s3FileTransferRequestParamsDto);
        // Assert that the proper delegate method is called with the expected params to retrieve credentials
        verify(mockDownloaderManifestReader).readJsonManifest(manifestPath);
        verify(mockDownloaderWebClient).getBusinessObjectData(downloaderInputManifestDto);
        verify(mockBusinessObjectDataHelper).getStorageUnitByStorageName(businessObjectData, storageName);
        verify(mockDownloaderWebClient).getS3KeyPrefix(businessObjectData);
        verify(mockS3Service).downloadDirectory(s3FileTransferRequestParamsDto);
    }
    finally
    {
        setLogLevel(DownloaderController.class, originalLevel);
        removeLoggingAppender(appenderName);
        /*
         * Restore mocked dependencies to their original implementation
         */
        ReflectionTestUtils.setField(downloaderController, "downloaderWebClient", originalDownloaderWebClient);
        ReflectionTestUtils.setField(downloaderController, "manifestReader", originalDownloaderManifestReader);
        ReflectionTestUtils.setField(downloaderController, "businessObjectDataHelper", originalBusinessObjectDataHelper);
        ReflectionTestUtils.setField(downloaderController, "s3Service", originalS3Service);
        ReflectionTestUtils.setField(downloaderController, "storageFileHelper", originalStorageFileHelper);
        ReflectionTestUtils.setField(downloaderController, "storageHelper", originalStorageHelper);
        // Clean up any temporary files
        FileUtils.deleteDirectory(localPath.toFile());
    }
}