# Junit und Mocks bei JDBC Daos



## mvitz (17. Jul 2009)

Hallo zusammen,

angenommen man baut seine DAOs direkt auf reinem JDBC auf und möchte diese mit Junit tests absichern. Man benötigt idR. eine DataSource, die in das DAO hineingegeben wird. Über die DataSource kommt man an die Connection, darüber wieder an ein Statement und darüber evtl. noch an ein ResultSet.

Bei benutzung eines Mock Frameworks, resultiert das ganze schonmal in einige Zeilen:

1x für jedes der 4 Objekte Mock erzeugen => 4
1x für Connection, Statement und ResultSet zum closen => 3
dann noch getConnection, prepareStatement, executeQuery, next(), und getString() sind nochmal 5. Also so ca. 12 Zeilen.

Wie macht ihr das, ich finde das ganze einen sehr großen Aufwand.


----------



## faulelotte (18. Jul 2009)

> angenommen man baut seine DAOs direkt auf reinem JDBC auf und möchte diese mit Junit tests absichern.


Schreibe diesen Test lieber gegen eine echte Datenbank als Integrationstest.

Anti-patterns with Mock Objects


----------



## maki (18. Jul 2009)

> Wie macht ihr das, ich finde das ganze einen sehr großen Aufwand.


In Dao Tests zu Mocken finde ich nicht so dolle.
Daos teste ich mit Integrationstests und nutze DBUnit um mir diese Sache zu erleichtern, zusammen mit Spring 
In anderen Tests verwende ich natürlich Mock-Daos anstatt echter.

Sehr interessant imho: Back Door Manipulation at XUnitPatterns.com
Speziell der Absatz "Example: Back Door Fixture Setup".


----------



## mvitz (18. Jul 2009)

maki hat gesagt.:


> In Dao Tests zu Mocken finde ich nicht so dolle.
> Daos teste ich mit Integrationstests und nutze DBUnit um mir diese Sache zu erleichtern, zusammen mit Spring
> In anderen Tests verwende ich natürlich Mock-Daos anstatt echter.
> 
> ...



Du benutzt doch auch maven, oder?

Wie setzt du/ihr in maven denn dann die Integrationstest auf?


----------



## faulelotte (18. Jul 2009)

habi55 hat gesagt.:


> Du benutzt doch auch maven, oder?
> 
> Wie setzt du/ihr in maven denn dann die Integrationstest auf?



Ich weiß nicht ob im neuen Maven 2.2.0 schon Unterstützung dafür drin ist, es sollte nämlich eine extra Phase it-test für Integrationstests eingeführt werden.

Ansonsten liegen meine Integrationstests momentan zusammen mit den Unittests. Das sind bei mir auch JUnit Tests. (unter zuhilfenahme von DBUnit usw.)
Sauberer wäre vielleicht die Integrationstests in ein einzelnes Maven Module zu verschieben.


----------



## maki (18. Jul 2009)

Es gab bereits eine IT Phase in Maven2, allerdings muss man Package aufrufen um sicherzustellen das die Phase after-it aufgerufen wurde(oder ähnlich), aus diesen und anderen Gründen (Komplexität) sollte man IT Tests in eigene Module auslgern, aber DAO Integrationstests habe ich immer in meiner normalen Testphase aufgerufen (zB. mit einer HSQLDB), waren auch immer teil des selben Moduls.
Wenn man WebApp oder EJBs in einem IT ausführt, mache ich das aber immer in eigenen Modulen und nutze dafür Selenium, Cactus, SpringDM oder andere Tools/frameworks/Libs.


----------



## faulelotte (18. Jul 2009)

maki hat gesagt.:


> aus diesen und anderen Gründen (Komplexität) sollte man IT Tests in eigene Module auslgern, aber DAO Integrationstests habe ich immer in meiner normalen Testphase aufgerufen (zB. mit einer HSQLDB)



Da Integrationstests ja gegen eine echte Datenbank gehen und diese meistens einige Größenordnungen langsamer sind als reine Unittests, lohnt sich das mit dem auslagern auch. Spätestens wenn der Build wegen der Integrationstests irgendwann mehrere Minuten dauert.


----------



## maki (18. Jul 2009)

Ja, wenn der Integrationstest zu langsam wird, wird er ausgelagert, aber das war noch nicht der Fall bei "normalen" DaoTests, zumindest unter zuhilfename von Spring & Optimierungen, denn so ein Rollback ist meist schneller als Daten gezielt zu löschen oder gar ganze Tabellen bzw. Schemata und danach die DB komplett neu zu befüllen.

Eine Regel die ich hier habe, ist das alle Unittests unter 1 Minute laufen müssen, alle Integrationstests unter 10 Minuten. Die Unittests können so oft laufen, und die Interationstest zumindest vom dem Commit, falls doch was durchgeht findet dass der CI Server (Hudson).


----------



## byte (19. Jul 2009)

Wir testen die DAOs auch einfach als Unittests mit Spring. Benutzen ne embedded Apache Derby für die Tests. Mit Spring lässt sich das recht einfach integrieren. Benutzen TestNG als Testframework und 
	
	
	
	





```
org.springframework.test.context.testng. AbstractTransactionalTestNGSpringContextTests
```
.

Die Tests laufen auch recht zügig durch. Für alle weiteren Tests sollte man die DAOs dann aber mocken.


----------

