# Junit Tests durchführen



## mikeD (18. Jul 2012)

Ich habe hier eine Methode die Bestandteil einer "anlegen klasse" ist.

es soll überprüft werden, ob ein Kunde bereits in der datenbank vorhanden ist.
Die methode öffnet erst eine verbindung zur datenbank, dann werden die namensfelder vor/name ausgelesen. falls der name bereits vorhanden ist, wird eine execption geworfen, sonst wird ein comit durchgeführt (mysql).

sooooooo und jetzt soll ich hier keine Klassentest mit junit zu unter anderem dieser Methode schreiben.


jemand eine idee? ein paar vorschläge?

wie kann ich z.b die DATENBANKVERBINDUNG mit Junit TESTEN ?






```
public void kundePrüfen() throws Exception
	{
		
		if(gui.getField("NameEregbnis").getText().trim().isEmpty() == false && gui.getField("VornameErgebnis").getText().trim().isEmpty() == false)
		{
			verbindung = new datenbankverbindung();
			//Prüfung ob schon in der Datenbank vorhanden
			verbindung.ausgabebefehl("name, vorname", "kunde", "name = '"+gui.getField("NameEregbnis").getText().trim()+"' and vorname = '"+gui.getField("VornameErgebnis").getText().trim()+"'", null, null, null);
			
			if (verbindung.getDatenbankauszug().first() == true)
				throw new Exception ("Es ist schon eine Person mit diesem Namen in der Datenbank vorhanden");
			else
				verbindung.closeCommit();
		}
		else
			throw new Exception("Bitte geben sie einen Namen ein");
	}
```


----------



## Gast2 (18. Jul 2012)

Hm, so wie die Methode aufgebaut ist wird das nicht ganz trivial. Du instantiierst in der Methode eine Instanz von datenbankverbindung, die wohl dann ne Verbindung zur Datenbank aufbaut.
Damit bist du natürlich an diesen festen Ablauf gebunden und das ist für deinen Test nicht grad förderlich wie du wohl grad merkst 

Solche Abhängigkeiten werden in der Regel von außen gesetzt. Deine Klasse könnte beispielsweise im Konstruktor eine Instanz von datenbankverbindung aufnehmen.
Im produktiven code wäre das wirklich ne Klasse die zur Datenbank verbindet, in deinem Test könnte das aber irgend eine Dummyimplementierung sein die bspw. intern nur eine Map nutzt in dem nen paar Testdaten sind.
Das führt dann dazu dass du bei deinem Test keine DB brauchst.

Ein ähnliches Problem hast du übrigens mit deinen Textfields die da direkt abfragst.


----------



## maki (18. Jul 2012)

Für die Klasse datenbankverbindung köntest du (theoretisch) einen Unitest schreiben, zum testen der DB Persistenz etc. braucht man ja nicht die GUI mittesten.

Wie sieht denn der Code von datenbankverbindung aus?


----------



## mikeD (18. Jul 2012)

okay.

egal wie ich brauch dazu bis übermorgen 1-2 junit tests.... und habe 0 phantasie was ich da machen kann....

bitte IRGENDWELCHE vorschläge, egal was. vermutlich kommts nicht wirklich auf die qualität der tests drauf an, nur dass was getestet worden ist....

mfg


----------



## Deception (18. Jul 2012)

Hey,
muss der Code so bleiben?? 
Ich würde 1 oder 2 Codeänderungen an deiner Stelle vornehmen um es testbar zu machen.
So ist es der Schrecken eines jeden Testers.
Mit ein paar kleinen Änderungen kommst du auch sehr gut selbst mit den Unit-Tests zurecht.
Zunächst: definiere eine Eingabe und Ausgabe! 
Die Eingabe können zum Beispiel die String aus den Textfeldern sein.
Die Ausgabe deine Exception Strings, die du dann später in eine Exception packst.
Das ist auch nicht schön, damit hast du aber eine testbare Methode, denn:
Du kannst als Eingabe eigene Namen in die Methode werfen von denen du weißt ob sie in der Datenbank existieren oder nicht und das Ergebnis mit der Erwartung abgleichen.

Das ist dann ein handlicher JUnit-Test mit wenigen Testfällen, den man in 20 mins schreiben kann ohne zusätzliche Technologien zu verwenden! 
Hier müsste man schon mal mit PowerMockito o.ä. ran.
Viel Erfolg,
Jens

PS: aus welcher Programmiersprache kommst du ursprünglich?  Es fällt auf das übliche Java Konventionen nicht eingehalten sind.


----------



## mikeD (18. Jul 2012)

ja er muss so bleiben...

sorry.


----------



## bERt0r (18. Jul 2012)

Also erstmal würde ich der Methode einen (oder mehr?) String als Parameter übergeben, den sie Prüfen soll. Das auslesen des Inhalts von Textfeldern passt mMn nicht zur Tätigkeit "Prüfen ob ein Name schon in der Datenbank existiert".


----------



## mikeD (18. Jul 2012)

bin offen für konkrete beispiele

mfg


----------



## nillehammer (18. Jul 2012)

Den Code *kann* man garnicht unit-testen, weil hier Funktionalitäten in einer Methode zusammengeklebt sind, die nicht zusammen gehören. Der Code ist auch sonst einfach nur grausam. Sorry für dieses harte Urteil.

Das einzige, was ich mir hier sinnvoll vorstellen kann, ist ein Test über die GUI
- Fülle die Felder mit Werten, die noch nicht in der DB stehen
- Betätige das Element, dass die Methode kundePrüfen() auslöst (ich nehme an, ein Button?)
--> Erwartung: Es sollte keine Exception fliegen
- Fülle die Felder nochmal mit den gleichen Werten
- Betätige das Element, dass die Methode kundePrüfen() auslöst (ich nehme an, ein Button?)
--> Erwartungshaltung: Es sollte eine Exception fliegen.

Die Frage, wie man Felder befüllt und Buttons klickt, lässt sich beantworten, wenn bekannt ist, welche GUI-Technologie hier verwendet wird.


----------



## Deception (18. Jul 2012)

Hey,
sry, aber ich glaube du nimmst dir da nicht wirklich Zeit für.
Hier kamen viele Vorschläge... Von teste nur die Datenbankverbindung, über ändere den Code, bis hin zu Dependency Inversion durch reingeben der Datenbankverbindung über den Konstruktor.
Du lehnst sämtliches ab, obwohl dir gesagt wird, dass der Code so extrem schwer testbar ist.
Das minimal invasivste ist die Datenbankverbindung direkt zu testen.
Naja, ich wünsche dir viel Spaß und Erfolg dabei.
Beste Grüße,
Jens


----------



## mikeD (18. Jul 2012)

ich sag die wahrheit, ich fühl mich extrem überfordert

hier was ich bisher gemacht habe, ich kann natürlich nicht das ganze programm posten 


```
package Anwendung;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.*;

import Zwischenspeicher.Adresse;
import Zwischenspeicher.Bankverbindung;
import Zwischenspeicher.Kunde;
import Zwischenspeicher.Mietwagen;
import Zwischenspeicher.Zimmer;
import ButtonHandler.GuiAnlegen;
import ButtonHandler.ButtonAnlegen;
import datenbank.datenbankverbindung;
import static org.junit.Assert.*;

/**
 * The class <code>AnlegenTest</code> contains tests for the class <code>{@link Anlegen}</code>.
 *
 */
public class AnlegenTest {
	/**
	 * Run the Anlegen(ButtonAnlegen) constructor test.
	 *
	 * @throws Exception
	 *

	 */
	@Test
	public void testAnlegen_1()
		throws Exception {
		ButtonAnlegen button = new ButtonAnlegen(new GuiAnlegen());

		Anlegen result = new Anlegen(button);

		// add additional test code here
		
		
		
		assertNotNull(result);
	}

	/**
	 * Run the void kundeAnlegen() method test.
	 *
	 * @throws Exception
	 *

	 */
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testKundeAnlegen_1()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();

		fixture.kundeAnlegen();

		
		java.util.Date geburtsdatum = null;
		
		
			geburtsdatum = new SimpleDateFormat("yyyy-MM-dd").parse("1983-10-04");
	
		Date geburtstag = new java.sql.Date(geburtsdatum.getTime());
		
			int kundenid=100;
			Kunde testkunde1 = new Kunde(kundenid, "Franz", "Anton", "0156",geburtsdatum);
			
		int adressid = 100;
		Adresse testadresse1 = new Adresse(adressid, kundenid,"Volksstrasse","123b","PlzErgebnis",81825);
		
		
		
		
		
		int bankid = 100;
	
			Bankverbindung testbankverbindung1 = new Bankverbindung(bankid, kundenid,"Volksbank","7015000","12345678");
			
			//-----------------------------------
			
			int kundenid2=200;
			Kunde testkunde2 = new Kunde(kundenid2, "Franz", "Anton", "0156",geburtsdatum);
			assertNotNull("User not Created", testkunde1);
			int adressid2 = 200;
			Adresse testadresse2 = new Adresse(adressid2, kundenid2,"Volksstrasse","123b","PlzErgebnis",81825);
		
			int bankid2 = 200;
			Bankverbindung testbankverbindung2 = new Bankverbindung(bankid2, kundenid2,"Volksbank","7015000","12345678");
			
			
			///-------- Asserts
			assertNotNull(testkunde1);
			assertNotNull(testadresse1);
			assertNotNull(testbankverbindung1);	
			assertNotSame(testkunde1, testkunde2);
		}


	/**
	 * Run the void kundeAnlegen() method test.
	 *
	 * @throws Exception
	 *
	 */
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testKundeAnlegen_2()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();

		fixture.kundeAnlegen();

		
		java.util.Date geburtsdatum = null;
		
		
			geburtsdatum = new SimpleDateFormat("yyyy-MM-dd").parse("1983-10-04");
	
		Date geburtstag = new java.sql.Date(geburtsdatum.getTime());
		//fehlerhafte Kundendaten
			int kundenid=100;
			Kunde testkunde1 = new Kunde(kundenid, "1111", "1111", "1111",geburtsdatum);
			
		int adressid = 100;
		Adresse testadresse1 = new Adresse(adressid, kundenid,"Volksstrasse","123b","PlzErgebnis",81825);
		
	
		int bankid = 100;
	
			Bankverbindung testbankverbindung1 = new Bankverbindung(bankid, kundenid,"Volksbank","7015000","12345678");
			assertNotNull(testkunde1);
			assertNotNull(testadresse1);
			assertNotNull(testbankverbindung1);	
			
			
			
	}

	/**
	 * Run the void kundeAnlegen() method test.
	 *
	 * @throws Exception
	 *

	 */
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testKundeAnlegen_3()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();

		fixture.kundeAnlegen();

		java.util.Date geburtsdatum = null;
		
		
		geburtsdatum = new SimpleDateFormat("yyyy-MM-dd").parse("1983-10-04");

	Date geburtstag = new java.sql.Date(geburtsdatum.getTime());
	
		int kundenid=100;
		Kunde testkunde1 = new Kunde(kundenid, "Franz", "Anton", "0156",geburtsdatum);
		
		
	int adressid = 100;
	Adresse testadresse1 = new Adresse(adressid, kundenid,"Volksstrasse","123b","PlzErgebnis",81825);

	int bankid = 100;
	//fehlerhafte Bankverbindung?
		Bankverbindung testbankverbindung1 = new Bankverbindung(bankid, kundenid,"111111","eeeeee","eeeee");
		assertNotNull(testkunde1);
		assertNotNull(testadresse1);
		assertNotNull(testbankverbindung1);	
	}

	/**
	 * Run the void kundeAnlegen() method test.
	 *
	 * @throws Exception
	 *

	 */
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testKundeAnlegen_4()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();

		fixture.kundeAnlegen();


		java.util.Date geburtsdatum = null;
		
		
		geburtsdatum = new SimpleDateFormat("yyyy-MM-dd").parse("1983-10-04");

	Date geburtstag = new java.sql.Date(geburtsdatum.getTime());
	
		int kundenid=100;
		Kunde testkunde1 = new Kunde(kundenid, "Franz", "Anton", "0156",geburtsdatum);
		
		//fehlerhafte adresse?
	int adressid = 100;
	Adresse testadresse1 = new Adresse(adressid, kundenid,"11111111","eeeee","111111",81825);
	

	int bankid = 100;

		Bankverbindung testbankverbindung1 = new Bankverbindung(bankid, kundenid,"Volksbank","7015000","12345678");
		assertNotNull(testkunde1);
		assertNotNull(testadresse1);
		assertNotNull(testbankverbindung1);	
	}

	


	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testMietwagenanlegen_1()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();


		fixture.mietwagenanlegen();

		int mietwagenid=100;
		Mietwagen testmietwagen = new Mietwagen(mietwagenid, "Adc3234a","Van",120);
		
		assertNotNull("Mietwagen wurde nicht erstellt", testmietwagen);			
			
		}


	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testMietwagenanlegen_2()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();


		fixture.mietwagenanlegen();

		int mietwagenid=100;
		
		//fehleingabe Mietwagen?
		Mietwagen testmietwagen = new Mietwagen(mietwagenid, "","Van",120);
		
		assertNull(testmietwagen);			
			
		}
	
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testMietwagenanlegen_3()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();


		fixture.mietwagenanlegen();

		int mietwagenid=100;
		
		//fehleingabe Mietwagen?
		Mietwagen testmietwagen = new Mietwagen(mietwagenid, "sf32","",120);
		
		assertNull(testmietwagen);			
			
		}
	@Test(expected = java.lang.ClassNotFoundException.class)
	public void testZimmerAnlegen_1()
		throws Exception {
		Anlegen fixture = new Anlegen(new ButtonAnlegen(new GuiAnlegen()));
		fixture.verbindung = new datenbankverbindung();
		fixture.gui = new GuiAnlegen();

		fixture.zimmerAnlegen();

int zimmerid=100;
		
		
			Zimmer testzimmer = new Zimmer(zimmerid, "Honeymoon",10, 120);
			
			
			assertNotNull(testzimmer);
			
	}

	 


	/**
	 * Perform pre-test initialization.
	 *
	 * @throws Exception
	 *         if the initialization fails for some reason
	 *
	 
	 */
	@Before
	public void setUp()
		throws Exception {
		//brauchen wir nicht
	}

	/**
	 * Perform post-test clean-up.
	 *
	 * @throws Exception
	 *         if the clean-up fails for some reason
	 *
	 
	 */
	@After
	public void tearDown()
		throws Exception {
		//brauchen wir nicht
	}

	/**
	 * Launch the test.
	 *
	 * @param args the command line arguments
	 *
	 
	 */
	
	public static void main(String[] args) {
		new org.junit.runner.JUnitCore().run(AnlegenTest2.class);
		
			
	}}
```


----------



## mikeD (18. Jul 2012)

damit das sinn macht braucht ihr noch den rest der 

anlegen klasse:

ich fürchte mich jetzt schon vor dem BUCHUNGANLEGEN test....


```
[code=Java]package Anwendung;

import java.sql.Date;
import java.text.SimpleDateFormat;
import Zwischenspeicher.*;
import datenbank.datenbankverbindung;
import ButtonHandler.*;


import java.util.*;

/**
 *
 *	Klasse zur verwaltung des Anlegens eines neuen Objektes 
 */

public class Anlegen 
{
	ButtonAnlegen button;
	datenbankverbindung verbindung = null;
	Gui gui = null;
	
	
	public Anlegen(ButtonAnlegen button)
	{
		this.button = button;
		this.gui = button.gui;
	}
	
	
	/**
	 * Methode um zu überprüfen ob ein eingegebener Name schon in der Datenbank eingetragen ist
	 * @throws Exception
	 */
	public void kundePrüfen() throws Exception
	{
		
		if(gui.getField("NameEregbnis").getText().trim().isEmpty() == false && gui.getField("VornameErgebnis").getText().trim().isEmpty() == false)
		{
			verbindung = new datenbankverbindung();
			//Prüfung ob schon in der Datenbank vorhanden
			verbindung.ausgabebefehl("name, vorname", "kunde", "name = '"+gui.getField("NameEregbnis").getText().trim()+"' and vorname = '"+gui.getField("VornameErgebnis").getText().trim()+"'", null, null, null);
			
			if (verbindung.getDatenbankauszug().first() == true)
				throw new Exception ("Es ist schon eine Person mit diesem Namen in der Datenbank vorhanden");
			else
				verbindung.closeCommit();
		}
		else
			throw new Exception("Bitte geben sie einen Namen ein");
	}
	
	/**
	 * Methode zum anlegen eines Neuen Kunden-, Adress, und Bankverbindungsobjektes mit automatischer Vergabe der DatenbankIDs und Überprüfung auf Duplikate
	 * @throws Exception
	 */
	public void kundeAnlegen() throws Exception
	{
		
				try 
				{
					verbindung = new datenbankverbindung();
					//Vergabe der DatenbankIDs
					int kundenid;
					int adressid; 
					int bankid;

					verbindung.ausgabebefehl("idkunde", "kunde u", "not exists(Select idkunde from kunde v where u.idkunde = (v.idkunde - 1))", null, null, null);
					if(verbindung.getDatenbankauszug().first() == true)
					{
						System.out.println(verbindung.getDatenbankauszug().getInt(1)+1);
						kundenid = verbindung.getDatenbankauszug().getInt(1)+1;
					}
					else
						kundenid = 1;
											
					verbindung.ausgabebefehl("idadresse", "adresse u", "not exists(Select idadresse from adresse v where u.idadresse = (v.idadresse - 1))", null, null, null);
					
					if(verbindung.getDatenbankauszug().first() == true)
					{
						System.out.println(verbindung.getDatenbankauszug().getInt(1)+1);
						adressid = verbindung.getDatenbankauszug().getInt(1)+1;
					}
					else
						adressid = 1;
											
					verbindung.ausgabebefehl("idbankverbindung", "bankverbindung u", "not exists(Select idbankverbindung from bankverbindung v where u.idbankverbindung = (v.idbankverbindung - 1))", null, null, null);
					
					if(verbindung.getDatenbankauszug().first() == true)
					{
						System.out.println(verbindung.getDatenbankauszug().getInt(1)+1);
						bankid = verbindung.getDatenbankauszug().getInt(1)+1;
					}
					else
						bankid = 1;
					
					//Einfügen des neuen Kunden in die Datenbank
					java.util.Date geburtsdatum = new SimpleDateFormat("yyyy-MM-dd").parse(gui.getField("GeburtstagErgebnis").getText().trim());
					Date geburtstag = new java.sql.Date(geburtsdatum.getTime());
					
					Kunde neuerkunde = new Kunde(kundenid, gui.getField("NameEregbnis").getText().trim(), gui.getField("VornameErgebnis").getText().trim(), gui.getField("TelefonErgebnis").getText().trim(), geburtstag);
					Adresse adresse = new Adresse(adressid, kundenid, gui.getField("StrasseErgebnis").getText().trim(), gui.getField("HausnummerErgebnis").getText().trim(), gui.getField("OrtErgebnisTF").getText().trim(), Integer.parseInt(gui.getField("PlzErgebnis").getText().trim()));
					Bankverbindung bank = new Bankverbindung(bankid, kundenid, gui.getField("BankErgebnis").getText().trim(), gui.getField("BlzErgebnis").getText().trim(), gui.getField("KontoErgebnis").getText().trim());
					
					verbindung.eingabebefehl("kunde", null, neuerkunde.getString());
					verbindung.eingabebefehl("adresse", null, adresse.getString());
					verbindung.eingabebefehl("bankverbindung", null, bank.getString());
					
					verbindung.closeCommit();
				} 
				catch (Exception e)
				{
					verbindung.closeRollback();
					throw new Exception(e.toString());
				}
	}
	
	
	/**
	 * Methode zum anlegen eines Zimmerobjektes mit automatischer Vergabe der DatenbankIDs
	 * @throws Exception
	 */
	public void zimmerAnlegen() throws Exception
	{
		
		//Vergeben der ZimmerID
			try
			{
				verbindung = new datenbankverbindung();
				int zimmerid;
				
				verbindung.ausgabebefehl("idzimmer", "zimmer u", "not exists(Select idzimmer from zimmer v where u.idzimmer = (v.idzimmer - 1))", null, null, null);
				
				if(verbindung.getDatenbankauszug().first() == true)
				{
					zimmerid = verbindung.getDatenbankauszug().getInt(1)+1;
				}
				else
					zimmerid = 1;
				
				//Einfügen in die neue Datenbank
				Zimmer neueszimmer = new Zimmer(zimmerid, gui.getBox("ZimmerTypBox").getSelectedItem().toString().trim(), Integer.parseInt(gui.getBox("ZimmerBettenBox").getSelectedItem().toString()), Integer.parseInt(gui.getField("ZimmerPreisTF").getText().trim()));
				
				verbindung.eingabebefehl("zimmer", null, neueszimmer.getString());
				verbindung.closeCommit();
			}
			catch (Exception e)
			{
				verbindung.closeRollback();
				throw new Exception(e.toString());
			}

	}
	
	/**
	 * Methode zum anlegen eines Mietwagenobjektes mit automatischer Vergabe der DatenbankIDs und Überprüfung auf Duplikate
	 * @throws Exception
	 */
	public void mietwagenanlegen () throws Exception
	{
			//Prüfung ob eine Nummernschildnummer eingegben wurde
			if(gui.getField("MietwagenSchildTF").getText().trim().isEmpty() == false)
			{
				try
				{
					verbindung = new datenbankverbindung();
					//Prüfung ob das Auto schon vorhanden ist
					verbindung.ausgabebefehl("nummernschildnummer", "mietwagen", "nummernschildnummer = '"+gui.getField("MietwagenSchildTF").getText().trim()+"'", null, null, null);
					
					if (verbindung.getDatenbankauszug().first() == true)
						throw new Exception ("Nummernschildnummer schon vergeben");
						
					else
					{
						//Zuweisen der DatenbankID
						int mietwagenid;
						
						verbindung.ausgabebefehl("idmietwagen", "mietwagen u", "not exists(Select idmietwagen from mietwagen v where u.idmietwagen = (v.idmietwagen - 1))", null, null, null);
						
						if(verbindung.getDatenbankauszug().first() == true)
						{
							mietwagenid = verbindung.getDatenbankauszug().getInt(1)+1;
						}
						else
							mietwagenid = 1;
						
						//Einfügen des Mietwagens in die Datenbank
						Mietwagen neuermietwagen = new Mietwagen(mietwagenid, gui.getField("MietwagenSchildTF").getText().trim(), gui.getBox("MietwagenTypBox").getSelectedItem().toString().trim(), Integer.parseInt(gui.getField("MietwagenPreisTF").getText().trim()));
						
						verbindung.eingabebefehl("mietwagen", null, neuermietwagen.getString());
						verbindung.closeCommit();
					}
				}
				catch (Exception e) 
				{
					verbindung.closeRollback();
					throw new Exception(e.toString());
				}
			}
			else
				throw new Exception("Bitte eine Nummernschildnummer eingeben");
	}

	
	/**
	 * Methode zum anlegen eines Buchungsobjektes mit automatischer Vergabe der DatenbankIDs und Überprüfung auf Verfügbarkeit des Zimmers und des Mietwagens im angegebenen Zeitraumes
	 * @throws Exception
	 */
	public void buchungAnlegen () throws Exception
	{
		try
		{
			//Kunden erstellen
			verbindung = new datenbankverbindung();
			
			verbindung.ausgabebefehl("*", "Kunde", "idkunde = "+gui.getTable("Kundenauswahl").getModel().getValueAt(gui.getTable("Kundenauswahl").getSelectedRow(), 0), null, null, null);
			
			verbindung.getDatenbankauszug().next();
			Kunde kunde = new Kunde(verbindung.getDatenbankauszug().getInt(1), verbindung.getDatenbankauszug().getString(2), verbindung.getDatenbankauszug().getString(3), verbindung.getDatenbankauszug().getString(4), verbindung.getDatenbankauszug().getDate(5), verbindung.getDatenbankauszug().getInt(6));

			//Buchungsids
			int buchungsid;
			int zimmerbuchungsid;
			int mietwagenbuchungsid;
			
			//counter
			int counter1 = 0;
			
			//Zimmertage
			java.util.Date zimmervon;
			java.util.Date zimmerbis;
			
			Date zimmerdatumvon;
			Date zimmerdatumbis;
			
			//Mietwagentagetage
			java.util.Date wagenvon;
			java.util.Date wagenbis;
			
			Date wagendatumvon;
			Date wagendatumbis;
			
			//Gesamtbuchungstage und Buchungsdatum
			java.util.Date date;
			java.util.Date date2;
			GregorianCalendar cal = new GregorianCalendar();
			java.util.Date date3 = new java.util.Date();
			Date datumheute = new java.sql.Date(date3.getTime());
			
			//Zwischenspeicherobjekte
			ArrayList<Zimmerbuchung> zimmerbuchungen = new ArrayList<Zimmerbuchung>();
			ArrayList<Wagenbuchung> mietwagenbuchungen = new ArrayList<Wagenbuchung>();
			
			Zimmerbuchung[] arrayzimmerbuchung;
			Wagenbuchung[] arraywagenbuchung = null;
			Zimmerbuchung zimmerbuchung;
			Wagenbuchung mietwagenbuchung;
			
			Zimmer gebuchteszimmer;
			Mietwagen gebuchtermietwagen;
			Buchung buchung;
			
			
			
			//Gesamtbuchungstage Formatumwandlung
			if (this.gui.getField("VonLabelTF").getText().trim().isEmpty() == false)
				date = new SimpleDateFormat("yyyy-MM-dd").parse(this.gui.getField("VonLabelTF").getText().trim());
			else
				throw new Exception("Geben sie bitte ein Ankunftsdatum ein");
			
			if (this.gui.getField("BisLabelTF").getText().trim().isEmpty() == false)
				date2 = new SimpleDateFormat("yyyy-MM-dd").parse(this.gui.getField("BisLabelTF").getText().trim());
			else
				throw new Exception("Geben sie bitte ein Abfahrtsdatum ein");

			Date datumvon = new java.sql.Date(date.getTime());
			Date datumbis = new java.sql.Date(date2.getTime());

			
			//Buchungsid festlegen
			verbindung.ausgabebefehl("idbuchung", "buchung u", "not exists(Select idbuchung from buchung v where u.idbuchung = (v.idbuchung - 1))", null, null, null);
			
			if(verbindung.getDatenbankauszug().first() == true)
			{
				buchungsid = verbindung.getDatenbankauszug().getInt(1)+1;
			}
			else
				buchungsid = 1;
			
			//Zimmerbuchungsid festlegen
			verbindung.ausgabebefehl("MAX(idzimmerbuchung)", "zimmerbuchung u", null, null, null, null);
			
			if(verbindung.getDatenbankauszug().first() == true)
			{
				zimmerbuchungsid = verbindung.getDatenbankauszug().getInt(1)+1;
			}
			else
				zimmerbuchungsid = 1;
			
			//Mietwagenbuchungsid festlegen
			
			verbindung.ausgabebefehl("MAX(idmietwagenbuchung)", "mietwagenbuchung u", null, null, null, null);
			
			if(verbindung.getDatenbankauszug().first() == true)
			{
				mietwagenbuchungsid = verbindung.getDatenbankauszug().getInt(1)+1;
			}
			else
				mietwagenbuchungsid = 1;
			
			//Zimmerbuchungen erstellen Solange noch Zeilen mit Zimmerbuchungen existieren
			while (gui.getTable("Zusammenfassung").getRowCount() > counter1 && gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 0) != null)
			{
				//Datumseingaben einer Zeile prüfen
				if (gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 3).toString().trim().isEmpty() == false)
					zimmervon = new SimpleDateFormat("yyyy-MM-dd").parse(gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 3).toString().trim());
				else
					throw new Exception("Geben sie bitte ein Ankunftsdatum bei Zimmer "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 0)+"ein");
				
				if (gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 4).toString().trim().isEmpty() == false)
					zimmerbis = new SimpleDateFormat("yyyy-MM-dd").parse(gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 4).toString().trim());
				else
					throw new Exception("Geben sie bitte ein Abfahrtsdatum bei Zimmer "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 0)+"ein");
				
				zimmerdatumvon = new java.sql.Date(zimmervon.getTime());
				zimmerdatumbis = new java.sql.Date(zimmerbis.getTime());
				
				if(zimmerdatumbis.before(zimmerdatumvon)||zimmerdatumvon.before(datumvon)||zimmerdatumbis.after(datumbis)||zimmerdatumvon.equals(zimmerdatumbis))
					throw new Exception("Geben sie bitte gültige Daten bei Zimmer "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 0)+"ein");
				
				//Zimmerobjekt erstellen
				verbindung.ausgabebefehl("*", "zimmer", "idzimmer = "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 0), null, null, null);
				verbindung.getDatenbankauszug().next();
				gebuchteszimmer = new Zimmer(verbindung.getDatenbankauszug().getInt(1), verbindung.getDatenbankauszug().getString(2), verbindung.getDatenbankauszug().getInt(3), verbindung.getDatenbankauszug().getLong(4));
				
				//Tage ermittlen an denen das Zimmer belegt ist
				long belegtetage = (zimmerbis.getTime()-zimmervon.getTime())/(60000*60*24);
				
				//Zimmerbuchung für die einzelnen Tage erstellen
				for(int i = 0; i <= belegtetage; i++)
				{				
					zimmerbuchung = new Zimmerbuchung(zimmerbuchungsid, buchungsid, zimmerdatumvon, gebuchteszimmer);
					zimmerbuchungen.add(zimmerbuchung);
					
					//Um einen tag weitergehen
					cal.setTime(zimmerdatumvon);
					cal.add(Calendar.DATE, 1);
					zimmervon = cal.getTime();
					zimmerdatumvon = new java.sql.Date(zimmervon.getTime());
					
					zimmerbuchungsid++;
				}
				counter1++;
			}
			
			
			//Mietwagenbuchungen erstellen Solange noch Zeilen mit Mietwagenbuchungen existieren
			while (gui.getTable("Zusammenfassung").getRowCount() > counter1 && gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 1) != null)
			{
				//Datumseingaben einer Zeile prüfen
				if (gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 3).toString().trim().isEmpty() == false)
					wagenvon = new SimpleDateFormat("yyyy-MM-dd").parse(gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 3).toString().trim());
				else
					throw new Exception("Geben sie bitte ein Ankunftsdatum bei Mietwagen "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 1)+"ein");
				
				if (gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 4).toString().trim().isEmpty() == false)
					wagenbis = new SimpleDateFormat("yyyy-MM-dd").parse(gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 4).toString().trim());
				else
					throw new Exception("Geben sie bitte ein Abfahrtsdatum bei Mietwagen "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 1)+"ein");
				
				wagendatumvon = new java.sql.Date(wagenvon.getTime());
				wagendatumbis = new java.sql.Date(wagenbis.getTime());
				
				if(wagendatumbis.before(wagendatumvon)||wagendatumvon.before(datumvon)||wagendatumbis.after(datumbis)||wagendatumvon.equals(wagendatumbis))
					throw new Exception("Geben sie bitte gültige Daten bei Mietwagen "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 1)+"ein");
				
				//Mietwagenobjekt erstellen
				verbindung.ausgabebefehl("*", "mietwagen", "idmietwagen = "+gui.getTable("Zusammenfassung").getModel().getValueAt(counter1, 1), null, null, null);
				verbindung.getDatenbankauszug().next();
				gebuchtermietwagen = new Mietwagen(verbindung.getDatenbankauszug().getInt(1), verbindung.getDatenbankauszug().getString(2), verbindung.getDatenbankauszug().getString(3), verbindung.getDatenbankauszug().getLong(4));
				
				//Tage ermittlen an denen der Mietwagen belegt ist
				long belegtetage = (wagenbis.getTime()-wagenvon.getTime())/(60000*60*24);
				
				//Mietwagenbuchung für die einzelnen Tage erstellen
				for(int i = 0; i <= belegtetage; i++)
				{				
					mietwagenbuchung = new Wagenbuchung(mietwagenbuchungsid, buchungsid, wagendatumvon, gebuchtermietwagen);
					mietwagenbuchungen.add(mietwagenbuchung);
					
					//Um einen tag weitergehen
					cal.setTime(wagendatumvon);
					cal.add(Calendar.DATE, 1);
					wagenvon = cal.getTime();
					wagendatumvon = new java.sql.Date(wagenvon.getTime());
					
					mietwagenbuchungsid++;
				}
				counter1++;
			}
			
			//ArrayLists in Arreys umwandeln
			arrayzimmerbuchung = zimmerbuchungen.toArray(new Zimmerbuchung[zimmerbuchungen.size()]);
			if(mietwagenbuchungen.isEmpty() == false)
				arraywagenbuchung = mietwagenbuchungen.toArray(new Wagenbuchung[mietwagenbuchungen.size()]);
			
			//Buchungsobjekt erstellen
			if(mietwagenbuchungen.isEmpty() == false)
				buchung = new Buchung(buchungsid, kunde, datumheute, arrayzimmerbuchung, arraywagenbuchung);
			else
				buchung = new Buchung(buchungsid, kunde, datumheute, arrayzimmerbuchung);
			
			ExceptionView Gesamtpreisfenster = new ExceptionView("Der Gersamtpreis beläuft sich auf "+buchung.getPreis()+" Euro");
			
			//Änderungen in Datenbank schreiben
			//Buchung einfügen
			verbindung.eingabebefehl("buchung", null, buchung.getString());
			
			//Zimmer einfügen
			for(int i = 0; i < zimmerbuchungen.size();i++)
			{
				System.out.println(zimmerbuchungen.get(i).getString());
				verbindung.eingabebefehl("zimmerbuchung", null, zimmerbuchungen.get(i).getString());
			}
			
			//Mietwagen einfügen
			if(mietwagenbuchungen.isEmpty() == false)
			{
				for(int i = 0; i < mietwagenbuchungen.size();i++)
				{
					System.out.println(mietwagenbuchungen.get(i).getString());
					verbindung.eingabebefehl("mietwagenbuchung", null, mietwagenbuchungen.get(i).getString());
				}
			}
			
			//Kundenbuchungen erhöhen
			kunde.setAnzahlbuchungen(kunde.getAnzahlbuchungen()+1);
			
			verbindung.updatebefehl("kunde", "anzahlbuchung = "+kunde.getAnzahlbuchungen(), "idkunde = "+kunde.getKundennummer());
			
			verbindung.closeCommit();
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
			verbindung.closeRollback();
			throw new Exception(e.toString());
		}
	}
	
	 

}
```
[/code]


----------



## Deception (18. Jul 2012)

Ok, wofür brauchst du das? 
Eigentlich ist egal wofür, ich sehe keinen Grund dafür, ein Refactoring zu vermeiden! Wenn die Schnittstelle erhalten bleiben soll, kannst du trotz allem eine Methode erstellen (zur Not eine private) und an sie die Strings übergeben! Private Methoden kann man mit Reflection aufrufen und so testen. Dadurch bleibt die Schnittstelle erhalten und du hast eine Chance das zu testen! Andernfalls sehe ich richtig düster! :/ 
Wenn der Auftraggeber sagt das das nicht sein darf, dann sei ehrlich und sage das es so aber nicht geht!! Mache Vorschläge und warte seine Reaktion ab! Das ist sehr sehr unangenehm, aber das ist etwas das man als Programmierer lernen muss.
Beste Grüße,
Jens

PS: Wenn du doch irgendwie in der Befugnis bist den Code zu ändern, erwäge auch die Einteilung in Schichten! Lese dir dazu etwas zu Schichten Architektur durch. Du hast auf jedenfall eine Datenbank Schicht und solltest eine Facade zur Validierung einführen. Dazwischen einen Service für die Logik. Wenn du das machst, erhälst du ziemlich schnell testbarere Methoden.


----------



## mikeD (19. Jul 2012)

ich mach das zusammen mit nem freund....

ich kann den code nicht ändern, weil mein teil die tests sind und dieser code nicht von mir  kommt und ich nicht einfach drin rumwüllen kann....

aber ich werds mal ansprechen^^

das problem ist, die sache sollte bis heute abend abgeschlossen sein :/


----------



## Deception (19. Jul 2012)

Ja, rede mit ihm! Dann sollte das relativ schnell gegessen sein. In einem gemeinsamen Projekt sollte es erstmal keinen unantastbaren Code geben.


----------



## nillehammer (19. Jul 2012)

Deception hat gesagt.:
			
		

> Wenn die Schnittstelle erhalten bleiben soll, kannst du trotz allem eine Methode erstellen (zur Not eine private) und an sie die Strings übergeben! Private Methoden kann man mit Reflection aufrufen und so testen.


Streng nach dem Prinzip der Kapselung wäre hier 
	
	
	
	





```
private
```
 der korrekte Sichtbarkeitsmodifizierer. Ich habe das für Methoden, die ich testen will, aber ein wenig aufgeweicht. Methoden, die ich testen will, mache ich immer default-vislible (also kein Sichtbarkeitsmodifizierter). Da mein Unit-Test im selben Package liegt, kann dieser die Methode dann ohne Reflection aufrufen und von außen ist sie trotzdem nicht sichtbar. Spart einem beim Schreiben der Tests etwas Arbeit.


----------



## Deception (20. Jul 2012)

Hey,
bringt aber das Problem mit sich, dass man die Tests nur in dem Paket liegen haben kann. Ist geschmackssache, aber ich finde das nicht sehr elegant, weil man eine Abhängigkeit in der Struktur hat, die nicht nötig ist... Stell dir vor du hast so ca 100 Testklassen die darauf beruhen und willst dann eine restrukturierung im Sinne von der default Maven Struktur durchführen. Da bekommst du ein großes Problem  
Beste Grüße,
Jens


----------



## bygones (20. Jul 2012)

Deception hat gesagt.:


> Hey,
> bringt aber das Problem mit sich, dass man die Tests nur in dem Paket liegen haben kann. Ist geschmackssache, aber ich finde das nicht sehr elegant, weil man eine Abhängigkeit in der Struktur hat, die nicht nötig ist... Stell dir vor du hast so ca 100 Testklassen die darauf beruhen und willst dann eine restrukturierung im Sinne von der default Maven Struktur durchführen. Da bekommst du ein großes Problem
> Beste Grüße,
> Jens


klar wenn du deine packages umbenennst muss das package der Tests ebenso umbenannt werden. Ich versteh nicht so recht was die default Maven Struktur damit zu tun hat ? der ist es egal wie die packages heissen.

Im optimal fall testet man so und so nur die oeffentlichen Schnittstellen und wenn man Testgetrieben entwickelt hat stellen sich solche Fragen gar nicht, da dort private / protected methoden erst ueber refactoring von getestetem Code enstehen.

Da dies aber der optimal fall ist, macht man so und so schon Abstriche. Tests im selben package zu haben ist meiner Ansicht nach noch der bestmoegliche, wenn man es ueber Reflection loest ist dies nicht sofort beim refactoren bemerkbar


----------



## tfa (20. Jul 2012)

bygones hat gesagt.:


> wenn man es ueber Reflection loest ist dies nicht sofort beim refactoren bemerkbar


Jedenfalls fast sofort, denn auch und gerade beim Refactoring laufen natürlich auch ständig die Unit-Tests, und die werden im Zweifelsfall halt rot.


----------

