- Eine Sammlung der 75 besten(?) Blogs über das Testen von Software: abtstracta.us/blog/75-best-software-testing-blogs
- Werden manuelle Tests benötigt? Eine Antwort versucht dieser Blog zu geben.
- Und hier ein Beitrag zu dem Thema, wann ist Testautomatisierung sinnvoll.
- Ein Post über das Löschen von automatisierten Test.
- Wie ist mit nicht-deterministischen Tests umzugehen? Dieser Blog versucht das Thema zu beleuchten.
- Google´s Guava ist mittlerweile ein alter Hut und mit Java 8 sind viele Ideen aus Guava mit ins JDK eingeflossen. Dennoch lohnt sich ein Blick. Beispiel: Ranges, Throwables, Graphs
- Wiremock simuliert HTTP basierte APIs. Interessant ist die Wiremock API selber. Die Aufrufe für das Starten/Stoppen und Stubben der Methoden kann man bequem im Testcode integrieren oder man startet Wiremock als eigenständigen Service.
- Zahlen-, Datums- oder Währungskonvertierungen in Javascript? Dann empfiehlt sich Globalize.
- Ein Texteditor für das Web. Im Mittelpunkt der Funktionalität steht das gemeinsame, gleichzeitige Arbeiten an einem Dokument.
- Fefes Blog. Kennt ihr schon, oder?
- Brewcraft, die wahre Kunst Bier zu brauen. Hier gibt es alles für den Hobbybrauer. Mit einem interessanten Artikel über alkoholfreie Biere.
-
Das
java.util.Optional
lässt mich nicht in Ruhe. Auf der einen Seite bietet es neben#isPresent()
nette Abkürzungen wie#ifPresent()
,#orElse()
oder#orElseThrows()
. Auf der anderen Seite habe ich im Alltag das Gefühl, dass dasOptional
eine inflationäre Verwendung findet. Im www fand ich dazu die folgenden Artikel.- Nothing is better than optional. Zeigt die Pros und Cons zu dem Thema auf.
- Ein ausführlicher Artikel zu Optionals.
- Und hier ein tiefgründiger Text, warum
Optional
'broken' ist.
- Never, ever, use null for an Optional variable or return value.
- Never use Optional.get() unless you can prove that the Optional is present.
- Prefer alternative APIs over Optional.isPresent() and Optional.get().
- It’s generally a bad idea to create an Optional for the specific purpose of chaining methods from it to get a value.
- If an Optional chain has a nested Optional chain, or has an intermediate result of Optional, it’s probably too complex.
- Avoid using Optional in fields, method parameters, and collections.On a related note, I thought of another rule after I presented the session: Don’t use an Optional to wrap any collection type (List, Set, Map). Instead, use an empty collection to represent the absence of values.
Dienstag, Mai 29, 2018
Links der Woche
Dienstag, Mai 22, 2018
Hibernate und java.util.Date
java.util.Date
Typ einer Eigenschaft aus einer Hibernate Entity. Dieses Datumsfeld wurde für einen Vergleich mit einem anderen Datum herangezogen. Als Beispiel dient die Entity Person
mit dem Datumsfeld #geburtstag
. Die interessanten Dinge finden sich in (1) und (2). Bevor die Entity in der Datenbank angelegt wird, ist alles wie erwartet. Das java.util.Date
ist ein java.util.Date
. Der Vergleich liefert ebenfalls ein positives Ergebnis.
@Entity
@Table("PERSON")
public class Person {
@Id
@Column(name = "PERSON_ID")
private Long personId;
@Column(name = "NAME")
private String name;
@Column(name = "VORNAME")
private String vorname;
@Column(name = "GEBURTSTAG")
private java.util.Date geburtstag;
...
}
final Date date = new DateTime(2018, 5, 22, 17, 0, 0).toDate();
Person person = new Person();
person.setGeburtstag(date);
person.setName("Name");
person.setVorname("Vorname");
// (1) Vergleich vor #save() und #refresh()
assertThat(person.getGeburtstag()).isInstanceOf(Date.class);
assertThat(person.getGeburtstag()).isNotInstanceOf(java.sql.Timestamp.class);
assertThat(person.getGeburtstag()).isEqualTo(date);
getSessionFactory().getCurrentSession().saveOrUpdate(person);
getSessionFactory().getCurrentSession().refresh(person);
// (2) Vergleich nach #save() und #refresh()
assertThat(person.getGeburtstag()).isInstanceOf(Date.class);
assertThat(person.getGeburtstag()).isInstanceOf(java.sql.Timestamp.class);
assertThat(person.getGeburtstag()).isNotEqualTo(date);
// IS NOT EQUAL, weil java.sql.Timestamp!
assertThat(now).isEqualTo(newRound.getDateTime());
// IS EQUAL! java.util.Date benutzt für den Vergleich long getTime()
Nach dem persistieren der Daten geschehen die bemerkenswerten Dinge. Aus dem java.util.Date
wird ein java.sql.Timestamp
. Das wäre nicht weiter tragisch, wenn nicht der Vergleich assertThat(person.getGeburtstag()).isNotEqualTo(now);
positiv ausfallen würde.
Was ist passiert? Mit dem refresh
wurde die Entity Person
neu aus der Datenbank gelesen, d.h. Hibernate liest per JDBC Verbindung die Daten aus der Datenbank. Für eine Timestamp
Spalte lautet der entsprechende JDBC Typ java.sql.Timestamp
, welcher von java.util.Date
abgeleitet ist. In der #equals()
Methode von java.sql.Timestamp
findet sich der Hinweis:
true if the given Object is an instance of a Timestamp that is equal
to this Timestamp object; false otherwise
D.h. ein Vergleich von java.sql.Timestamp
und java.util.Date
ist immer false
. Umgekehrt funktioniert der Vergleich: assertThat(now).isEqualTo(newRound.getDateTime());
, da java.util.Date#equals() für den Vergleich auf das Ergebnis der Methode #getTime()
zugreift. Das beste ist, man umgeht dieses Problem und verwendet gleich das java.time.LocalDateTime
aus JDK 8 oder höher. Falls diese Option nicht besteht, empfiehlt sich für den Vergleich die #compare()
Methode. java.sql.Timestamp
implementiert #compare(Timestamp)
und ein #compare(Date)
.
Donnerstag, Mai 17, 2018
Mockito Stubbing
Mockito gibt dem Entwickler zwei Möglichkeiten an die Hand, Methoden zu stubben. Variante 1, und vermutlich die beliebteste, ist die when/thenReturn
Variante. Die Variante 2 doReturn/when
dreht die Syntax um. Ein wesentlicher Unterschied zwischen den beiden Methoden ist die Typsicherheit der Variante 1.
when(mockOfClassXy.methodCall(anyParam())).thenReturn(anObject);
Der Typ von anObject
muss dem Rückgabetyp der Methode #methodCall(...)
entsprechen. Im Gegensatz zu der Variante 2
doReturn(anObject).when(mockOfClassXy).methodCall(anyParam());
kann anObject
ein beliebiger Typ sein. Der Fehler wird erst zur Laufzeit entdeckt. Für das Stubben von void
Methoden muss auf Variante 2 zurückgegriffen werden. Statt doReturn
wird doNothing
verwendet. Beispiel:
doNothing().when(mockOfClassA).voidMethodCall(anyParam());
Das stört bei strikter Verwendung von Variante 1 den Lesefluß. Teilweise gibt es hier die Empfehlung ganz auf Variante 1 zu verzichten und komplett auf Variante 2 umzusteigen. Wie gesagt, würde man dann auf die Typprüfung verzichten. Insbesondere bei ‘großen’ Projekten mit langen Testausführungszeiten wäre das vermutlich ein Problem.
Auf Stackoverflow finden sich zu dem Thema massig Einsendungen. Hier ein Beispiel:
Mockito when/thenReturn
vs doReturn/when
Links der Woche
- CSV Dateien verarbeiten mit Javascript? Vielleicht verrückt. Hier ist eine Lösung: papaparse
- Auf Heise gibt es einen Kommentar zu den aktuellen Problemen mit EFail und der Aufregung, dass PGP kaputt sei: heise.de
- Eine Javascript Bibliothek zum Zeichnen von Diagrammen. Die Diagramme versuchen möglichst handgemalt auszusehen. Das lässt das Ganze weniger steril wirken: Rough.js
- Für C++ Programmierer ein Muss. Der CPP Core Guide von und mit Bjarne Stroustrup zu finden auf GitHub:
- Eine Alternative zu Angular und anderen -eher schwergewichtigen- Frameworks. cujojs.com. Cujo orientiert sich wieder mehr an den Web-Standards und an den Möglichkeiten, die Javascript bietet.
- Fear of the Dark. Interpretiert von den Mozart Heros: Fear of the Dark
AssertJ und java.util.List
AssertJ hat eine praktische Möglichkeit, Listen in JUnit Tests abzuprüfen. Insbesondere, wenn in der Liste komplexe Objekte abgelegt sind, s...
-
Wer das erste mal einen klassischen Rest-Service mit Spring schreibt, also einen @RestController implementiert, der JSON (application/json;...
-
Die Tastensteuerung im VI kann ich mir nur grob granular merken. Deswegen dieser Versuch, die Sachen einmal aufzuschreiben und natürlich neb...
-
DOS-Box: Next Generation Wer als Entwickler behauptet, er arbeitet unter Windows, der erntet von seinen Linux/MacOS Kollegen ein müdes läch...