Ein paar Schnipsel im Java-Umfeld.
Es ist eigentlich recht schwer, ein paar "Schnipsel" in Java anzubieten, da die Sprache größtenteils vom Zusammenspiel der Objekte und der Verwendung div. OOP-Design-Pattern. Trotzdem gibt es ein hoffentlich ein paar Zeilen, welche das Leben erleichtern können?!
Nun stand ich die Tage vor der Aufgabe, zu testen, ob in einer Situation eine Log-Ausgabe erzeugt wird. Das kann man natürlich sehen, wenn man den Test ausführt - es soll aber automatisch getestet werden.
Also habe ich überlegt, wie ich denn ggf. das Logging-Framework mocken könnte. Das geht abernicht einfach, da ich den Logger per Lombok injeziert hatte. Aber - man kann ja dann auf die log-Variable zugreifen. Wie aber nun dort noch einbauen, dass überprüfbar wird, dass geloggt wurde?? Wie sollte das gehen?
Eigentlich ganz einfach. Man schreibt einen eigenen Appender. Dieser speichert die Logging-Events in einer Liste, die dann in dem Test abgefragt werden kann:
public class TestAppender extends AppenderSkeleton { @Getter private List<String> messages = new ArrayList<>(); @Override protected void append(LoggingEvent loggingEvent) { String msg = loggingEvent.getMessage().toString(); messages.add(msg); } @Override public void close() { // } @Override public boolean requiresLayout() { return false; } }
In der Test-Klasse kann das nun folgendermaßen verwendet werden:
@Test void getValueTest() { Logger logger = Logger.getLogger(ExcelRow.class); TestAppender appender = new TestAppender(); logger.addAppender(appender); assertEquals("Group-1", row.getStringValue("Surname)); assertEquals("Found multiple definitions for row 'USER_GROUP'.",
appender.getMessages().get(0));
}
Die hier verwendete Methode Appender::getMessages() liefert eine Liste von org.apache.log4j.spi.LoggingEvent zurück. Diese hat noch weitere Methoden, um bspw. den verwendeten Log-Leven o.ä. abzufragen - das würde aber dem Rahmen dieses Artikels sprengen und bleibt dem geneigten Programmierer überlassen...
Fertig - so testet man, ob Log-Ausgaben per Log4j erzeugt worden sind... :-)
Ein häufig in Enterprise-Anwendungen auftauchendes Problem sind NullPointerExceptions. Um diese zu umgehen, kann man einen "Wrapper" nutzen, welcher die Referenzen auf Objekte einpackt und Möglichkeiten bietet, mit Null-Values umzugehen: java.util.Optional
Einer der "Anwendungsfälle" kann der folgende sein:
private String getValueFromField(String fieldName) {
...
return value;
}
private void handleValues() {
String val = getValueFromField("Caption");
if (val != null) {
baseObject.setCaption(val);
}
}
kann bei Verwendung von Optional ersetzt werden durch:
private Optional<String> getOptionalValueFromField(String fieldName) {
...
return Optional.ofNullable(value);
}
private void handleValues() {
getOptionalValueFromField("Caption").ifPresent(baseObject::setCaption);
getOptionalValueFromField("editDate").ifPresent(baseObject::setEditDate);
getOptionalValueFromField("author").ifPresent(baseObject::setAuthor);
....
}
Da get[Optional]ValueFromField()
nun ein Optional<String>
zurück gibt, kann man die Methoden von Optional anwenden. Eine dieser Methoden ist ifPresent()
, welche einen Consumer als Parameter erwartet. So kann man den Code m.M. etwas übersichtlicher gestalten.