Introductie tot testen in Java
Maria Milusheva
Senior Software Engineer
In de vorige les en oefeningen testten we via assertions op returnwaarden.
Maar wat als er geen returnwaarden zijn?
Wat als returnwaarden niet belangrijk of informatief zijn?
Voorbeeld: opslaan in een database.

Database - een digitale opslagplaats voor het bewaren, beheren en beveiligen van gestructureerde gegevens. Er zijn veel databaseproviders:

Databaseservers zijn duurzaam, veilig, betrouwbaar en hebben vrijwel onbeperkte capaciteit
Echte databases zijn te groot en complex voor unit tests (wel bruikbaar in integratietests)
Stel dat we logs verwerken:
public class MessageProcessor {
private InfoStore infoStore; // Slaat info-logberichten hier op
private ErrorStore errorStore; // Slaat error-logberichten hier op
public void saveMessage(String message) {
if (message.startsWith("[INFO]")) {
infoStore.save(message);
}
if (message.startsWith("[ERROR]")) {
errorStore.save(message);
}
}
}
Voor de test zijn alleen basisinterfaces nodig:
// Blueprints voor InfoStore en ErrorStore
// Mocks hebben geen volledig geïmplementeerde klassen nodig
interface InfoStore {
void save(String message);
}
interface ErrorStore {
void save(String message);
}
Hoe testen we dat een bericht is opgeslagen zonder databases te maken?
Controleer dat een mock is gebruikt:
import static org.mockito.Mockito.verify;
Controleer dat een mock niet is gebruikt:
import static org.mockito.Mockito.verifyNoInteractions;
@Test void process_savesToInfoStore_whenInfoMessage() { InfoStore infoStore = mock(InfoStore.class); ErrorStore errorStore = mock(ErrorStore.class); MessageProcessor messageProcessor = new MessageProcessor(infoStore, errorStore);String message = "[INFO] Process started."; messageProcessor.saveMessage(message); // Zal InfoStore of ErrorStore gebruiken// Controleer welke van de twee databases is gebruikt verify(infoStore).save(message); verifyNoInteractions(errorStore); }
Wat als het bericht dat we maken in plaats daarvan is:
String message = "[ERROR] Process failed!"
Dan zien we testfouten zoals:
Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
We kunnen exact controleren hoe vaak een log is aangeroepen:
import static org.mockito.Mockito.times;
List<String> messages = new ArrayList<>(); // Maak lijst en voeg elementen toe messages.add("[INFO] Processing data..."); messages.add("[INFO] Processing data..."); messages.add("[INFO] Processing data..."); messageProcessor.saveMessageList(messages); // Sla de drie berichten opverify(infoStore, times(3)).save("[INFO] Processing data...");
Introductie tot testen in Java