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?
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 –
Haben Sie versucht, ddexManagerPool.getTarget() nachzuahmen, um einen verspotteten DdexManager zurückzugeben, der beim Aufruf von getExternalReleaseFromLiteDdex zurückgibt, was Sie wollen? –
Das hat @NicolasFilotto funktioniert Das hat alle meine kaputten Tests behoben. Danke :) – noobcoder