2016-05-06 7 views
1

Ich habe eine Methodenimplementierung, die eine funktionale Schnittstelle (Java 8) aufruft und ich versuche, einen Komponententest dafür zu schreiben. Hier ist die Methode, die ich testen will:Mocking Funktionsschnittstelle Anruf in Java

// Impl 
public Optional<ExternalRelease> getStagedRelease(AccessParams accessParams) throws DigitalIngestionException { 
    String resourcesPath=getReleaseResourcesPath(accessParams).orElseThrow(() -> new ValidationException(WRONG_ACCESS_CONTEXT_EXCEPTION)); 
    String ddexFilePath=getReleaseDdexPath(accessParams).get(); 
    if(stageDataManager.directoryExists(resourcesPath)) { 
     List<Track> tracks = getTracks(accessParams). 
          orElse(new ArrayList<>()); 
     ExternalRelease externalRelease = null; 
     //Verify if lite XML already exists 
     if(stageDataManager.fileExists(ddexFilePath)) { 
      //Load externalRelease values 
      String liteDdex = stageDataManager.loadFileContent(ddexFilePath). 
           orElseThrow(() -> new ProcessException("Lite DDEX content couldn't be read.")); 
      externalRelease = ddexManagerExecutor((ddexManager) -> ddexManager.getExternalReleaseFromLiteDdex(liteDdex)). 
           orElseThrow(() -> new ProcessException("External release couldn't be parsed from Lite DDEX.")); 
      externalRelease.setTracks(tracks); 
      return Optional.ofNullable(externalRelease); 
     } else { 
      //Create lite ddex if it doesn't exist 
      ExternalRelease releaseFromTracks=getReleaseFromTracks(tracks); 
      String liteDdex = ddexManagerExecutor((ddexManager) -> ddexManager.getLiteDdexFromAccessParamsAndExternalRelease(accessParams, releaseFromTracks)). 
           orElseThrow(() -> new ProcessException("Lite DDEX content couldn't be generated.")); 
      stageDataManager.writeStringInFile(ddexFilePath, liteDdex); 
      return Optional.ofNullable(releaseFromTracks); 
     } 
    } else { 
     return Optional.empty(); 
    } 
} 

Beachten Sie die Zeile innerhalb der zweiten IF

externalRelease = ddexManagerExecutor((ddexManager) -> ddexManager.getExternalReleaseFromLiteDdex(liteDdex)).orElseThrow(() -> new ProcessException("External release couldn't be parsed from Lite DDEX."));` 

Der ddexManagerExecutor ist eine funktionale Schnittstelle mit Java 8 Funktionen:

public interface ddexManagerConsumer<R> { 
    R process(DdexManager ddexManager) throws ProcessException; 
} 

private <R> R ddexManagerExecutor(ddexManagerConsumer<R> action) throws ProcessException { 
    DdexManager ddexManager = null; 
    try { 
     ddexManager = (DdexManager) ddexManagerPool.getTarget(); 
     return action.process(ddexManager); 
    } catch (Exception e) { 
     throw new ProcessException("Error while accessing to ddexManager pool."); 
    } finally { 
     try { 
      ddexManagerPool.releaseTarget(ddexManager); 
     } catch (Exception e) { 
      log.error("Error while releasing ddexManager instance.", e); 
     } 
    } 
} 

So in meine Unit-Tests, die ich versuche, die folgenden zu tun,

@Test 
public void getStagedReleaseTest_whenFileDoesNoExist() throws Exception{ 
    AccessParams accessParams = getDefaultAccessParams(); 
    File file = new File("src/test/resources/testTrack.mp3"); 
    String xml="<xml/>"; 
    accessParams.setFileName("testTrack.mp3"); 
    accessParams.setReleaseSlug("test-release-slug"); 
    Optional<List<File>> mockFileList = Optional.of(Arrays.asList(file)); 

    when(mockedStageDataManager.directoryExists(any())).thenReturn(true); 
    when(mockedStageDataManager.getResources(anyString(), any())).thenReturn(mockFileList); 
    when(mockedStageDataManager.fileExists(anyString())).thenReturn(false); 
    when(mockedStageDataManager.loadFileContent(anyString())).thenReturn(Optional.of(xml)); 
    when(mockedDdexManager.getLiteDdexFromAccessParamsAndExternalRelease(any(), any())).thenReturn(Optional.of(xml)); 

    DigitalIngestionServiceImpl serviceSpy = spy(service); 

    Optional<ExternalRelease> externalRelease = serviceSpy.getStagedRelease(accessParams); 
    Assert.assertNotNull(externalRelease); 


} 

Das bricht meinen Komponententest, da ich den Aufruf für die private Funktionsschnittstelle nicht verspottete. Ich Buchhaltung einfach für spöttische die folgende innere Linie:

ddexManager.getExternalReleaseFromLiteDdex(liteDdex) 

aber kein für den funktionalen Schnittstelle Aufruf, der die obige Methode aufruft. Irgendeine Ahnung, wie man das erreicht?

+0

es aus Thema ist aber keine Notwendigkeit Optional.ofNullable (externalRelease) in Ihrem Fall zu tun, wie externalRelease nicht sein kann null Verwendung Optional.of statt –

+1

Haben Sie versucht, ddexManagerPool.getTarget() nachzuahmen, um einen verspotteten DdexManager zurückzugeben, der beim Aufruf von getExternalReleaseFromLiteDdex zurückgibt, was Sie wollen? –

+0

Das hat @NicolasFilotto funktioniert Das hat alle meine kaputten Tests behoben. Danke :) – noobcoder

Antwort

1

Sie können ddexManagerPool.getTarget() um verspotten eine verspottete DdexManager zurückzuversetzen zurückkehren, was Sie wollen, wenn getExternalReleaseFromLiteDdex Aufruf