Saying Hello
Introductie
Gegevens Opvragen
Gegevens Aanpassen
Geavanceerde Onderwerpen
Los gekoppelde systemen
Eind Opdracht:Sweet Kitty Shop
Saying Goodbye

Embedded Test Database

Eerst en vooral hebben we een test databank nodig. Deze databank moet offline draaien, zodat een internet connectie onze tests niet kan doen falen, en moet ingewerkt (embedded) zijn in onze test omgeving.

Hiervoor gaan we gebruik maken van hsqldb. Dit is, net als MySQL en MariaDB, een SQL Server, maar met dat verschil dat deze databank ingewerkt zit in onze code. Deze bestaat dus enkel in het geheugen van onze computer, en voor onze doeleinden, enkel als de testen lopen. Dit noemen we ook vaak een in memory Database.

Als eerste stap om hier mee aan de slag te gaan, moeten we de test databank van gegevens kunnen voorzien. Dit zal gebeuren aan de hand van een schema.sql en een data.sql bestand.

schema.sql. Bevat de gegevens over de databank en de tabellen met hun attributen.

data.sql. Bevat de eigenlijke test gegevens waarmee we de databank gaan vullen. Deze dienen enkel om testen te kunnen uitvoeren en dus methoden te testen.

Voor onze bieren volstaat het om de volgende documenten te hebben. Deze dien je op te slaan in de map src > test > resources

Schema.sql

CREATE TABLE if not exists Brewers (Id int IDENTITY not null, Name varchar(50) default NULL, Address varchar(50) default NULL, ZipCode varchar(6) default NULL,City varchar(50) default NULL, Turnover int default 0, PRIMARY KEY (Id));
CREATE TABLE Categories (Id int IDENTITY not null, Category varchar(50) default NULL,PRIMARY KEY  (Id));
CREATE TABLE Beers (Id int IDENTITY not null, Name varchar(100) DEFAULT NULL, BrewerId int DEFAULT NULL, CategoryId int DEFAULT NULL,Price float DEFAULT 0, Stock int DEFAULT 0, Alcohol float DEFAULT 0, Version int DEFAULT 0, Image blob, PRIMARY KEY (Id));

Data.sql

truncate table Brewers;
truncate table Categories;
truncate table Beers;

INSERT INTO Brewers VALUES (1,'TestBrewer','Test Street 911',1111,'Test-County',10000);
INSERT INTO Categories VALUES (1,'TestCategory');
INSERT INTO Beers VALUES (1,'TestBeer',1,1,2.75,100,7,0,NULL);

Met deze gegevens kunnen we al heel wat van onze automatische testen gaan uitvoeren. Voor bepaalde testen zullen we nog extra gegevens nodig hebben. Deze kunnen we dan toevoegen aan deze databank.

We houden deze ook bewust klein, maar volledig gelijk met de echte databank, zodat vlot alles getest kan worden en dat de verwachte gegevens snel terug te vinden zijn. Eveneens willen we de structuur op dezelfde manier behouden als de echte databank, zodat de testen representatief zijn.

Het testen of de application daadwerkelijk connectie maakt met de echte databank, is een integratie test en gaan we hier niet verder behandelen. Met onze Unit Tests kijken we of onze code doet wat het moet doen, onafhankelijk van de databank.


Nu is het tijd om de test databank op te bouwen. Hiervoor gaan we eerst de POM aanvullen om de HSQLDB te initializeren voor onze testen.

Hiervoor voegen we twee afhankelijkheden toe.

De eerste is die van HSQLDB zelf. Hierbij zal ook de driver worden ingeladen voor de HSQLDB database. Hiervan gebruiken we versie 2.4.0, en plaatsen we de scope op test. Deze database zal namelijk enkele nodig zijn om testen uit te voeren, dus deze hoeft niet mee verpakt te worden bij productie.

<dependency>
   <groupId>org.hsqldb</groupId>
   <artifactId>hsqldb</artifactId>
   <version>2.4.0</version>
   <scope>test</scope>
</dependency>

De tweede dependency hebben we nodig om onze data.sql en schema.sql bestanden te kunnen inlezen. Dit is een onderdeel van de ibatis frameworks en bibliotheken.

<dependency>
   <groupId>org.apache.ibatis</groupId>
   <artifactId>ibatis-core</artifactId>
   <version>3.0</version>
   <scope>test</scope>
</dependency>

Nu de configuratie klaar staat, kunnen we aan de slag met de configuratie voor onze testen te kunnen uitvoeren met deze databank. Hiervoor gaan we voor de eerste keer, in de BeforeEach van een testklasse, de volgende code toevoegen waar de connectie wordt gemaakt met de databank.

@BeforeEach
public void init() throws SQLException, Exception {
        try (
            Connection con = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "sa", "");
            Statement statement = con.createStatement();
            Reader schemaReader = new BufferedReader(new FileReader("src/test/resources/schema.sql"));
            Reader dataReader = new BufferedReader(new FileReader("src/test/resources/data.sql"))
    ){
            ScriptRunner runner = new ScriptRunner(con);
            runner.runScript(schemaReader);
            runner.runScript(dataReader);
    }
}

Eerst bouwen we onze Connectie op. Dit doen we nog steeds met de DriverManager.getConnection()

Hierbij zien we dat de url van een andere variant is. Eerst komt nogaltijd JDBC, want we gebruiken jdbc. Het subprotocol is hsqldb, want het is deze driver die we nu moeten inladen. Daarna komt een vermelding dat dit een in memory databank is (mem) en we geven hem een naam binnen het geheugen van de applicatie (mymemdb). Hierbij is het standaard gebruiker en wachtwoord bij hsqldb “sa” en een lege string.

Eenmaal we de connectie hebben opgebouwd, maken we de statements klaar om verder dit te kunnen gebruiken.

Eveneens bouwen we hier twee Input kanalen op die de gegevens uit de data.sql en het schema.sql inlezen. Ook deze zijn AutoCloseable en kunnen in de try with resources komen.

Met het script dat dan volgt, vullen we deze nieuwe databank nu met de gegevens uit het schema en data bestand respectievelijk. Hierbij gebruiken we de ScriptRunner klasse uit het Ibatis project, die ons helpt dit om te zetten naar SQL en dit uit te voeren naar de hsqldb databank.

Met deze voorbereidingen zijn we nu klaar om een eerste unit test op te gaan bouwen. Hierbij zullen we de te testen methode wel een stuk moeten aanpassen zodat we de unit test op een goede manier kunnen uitvoeren.