J'essaie de mettre en œuvre un JUnit test pour vérifier les fonctionnalités d'un DAO. (Le DAO créera/lira une relation élémentaire/table).
Le problème que je rencontre est la persistance de la DAO (pour le code non-test) est complétée par une solution interne utilisant Spring/Hibernate , ce qui élimine les *.hbm.xml
templates habituels que la plupart des exemples que j'ai. trouvé contenir.
De ce fait, j'ai du mal à comprendre comment configurer un JUnit test pour implémenter le DAO afin de créer/lire (fonctionnalités très élémentaires) sur un en mémoireHSQLDB. J'ai trouvé quelques exemples, mais l'utilisation de la persistance interne signifie que je ne peux pas étendre certaines des classes montrées dans les exemples (je n'arrive pas à obtenir correctement le paramètre application-context.xml).
Quelqu'un peut-il suggérer des projets/exemples que je pourrais consulter (ou toute documentation) pour approfondir ma compréhension du meilleur moyen de mettre en œuvre cette fonctionnalité de test? Je pense que cela devrait être très simple, mais je continue à avoir des problèmes pour mettre en œuvre les exemples que j'ai trouvés.
modifier:
Voici ma solution pour une meilleure lisibilité, pour tous ceux qui ont besoin d'aide:
Ma TestClass
:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContextTest-Example.xml")
@Transactional
public class ExampleDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
@Resource(name = "sessionFactory")
private SessionFactory exampleSessionFactory;
@Resource(name = "exampleDao")
private ExampleDao exampleDao;
Mon fichier applicationContext.xml
:
<!-- List of Daos to be tested -->
<bean id="exampleDao" class="org.myExample.ExampleDao"/>
<!-- Datasource -->
<bean id="example_dataSource"
class="org.Apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:ExampleTest"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<!-- Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="example_dataSource"/>
<property name="annotatedClasses">
<list>
<value>org.myExample.ExampleClass</value>
</list>
</property>
<property name="hibernateProperties">
.... left to user to choose properties
</property>
</bean>
Spring 3 propose un nouvel espace de noms jdbc
qui inclut la prise en charge des bases de données incorporées, y compris HSQLDB. Donc, cela prend soin de cette partie.
Je me demande quelle pourrait être la "solution interne". Vous pouvez utiliser des annotations (annotations JPA ou Hibernate) pour ORM vos objets de domaine, alors pourquoi avez-vous besoin d'une "solution interne"? Par exemple.:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:packagesToScan="myapp.model" />
En ce qui concerne la mise en œuvre d'un test, utilisez TestContext Framework de Spring. Un test peut ressembler à ceci (encore une fois, je suppose le printemps 3 ci-dessous, mais cela devrait fonctionner au printemps 2.5 en changeant simplement @Inject en @Autowired):
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"/beans-datasource-it.xml",
"/beans-dao.xml",
"/beans-service.xml",
"/beans-web.xml" })
@Transactional
public class ContactControllerIT {
@Inject private ContactController controller;
... setUp() and tearDown() ...
@Test
public void testGetContact() {
String viewName = controller.getContact(request, 1L, model);
... assertions ...
}
}
Vous placeriez la base de données intégrée dans beans-datasource-it.xml
, par exemple. ('it' représente ici un test d'intégration et les fichiers se trouvent sur le chemin de classe.) Dans cet exemple, le contrôleur vit dans beans-web.xml
et sera automatiquement câblé dans le champ ContactController
.
C'est juste un aperçu de ce qu'il faut faire, mais j'espère que c'est suffisant pour vous aider à démarrer.
J'ai récemment implémenté une solution similaire dans certains de mes codes en utilisant Hibernate , Spring et HSQLDB.
Il est à noter que AbstractTransactionalJUnit4SpringContextTests
est maintenant obsolète - mais il reste assez simple à tester - je couvre la plupart des détails ici: http://automateddeveloper.blogspot.com/2011/05/hibernate-spring-testing- dao-layer-with.html
Vois ici . Il suppose que maven2 est un outil de construction, mais vous pouvez facilement utiliser n'importe quoi.
Le résultat inférieur avec hibernation est la SessionFactory
- votre solution interne en créera très probablement une. Découvrez comment, puis ajoutez un bean pour en créer un dans le contexte de votre application de test de la même manière (ou, si possible, en utilisant votre code interne utilisé au moment de l'exécution.). Vous devrez peut-être créer votre propre FactoryBean pour faire l’instanciation. (Utilisez AbstractFactoryBean comme classe de base.)
Une fois que cela est en place, la plupart des exemples utilisant LocalSessionFactoryBean peuvent être migrés vers votre situation. Au lieu d'utiliser LocalsessionFactoryBean, utilisez votre bean d'usine personnalisé.
(Si vous ne l'avez pas déjà fait, examinez la section Testing de la référence Spring - elle simplifie les tests avec Spring et l'injection de tests avec des haricots du contexte.)
Mon contexte d'application est un peu différent
<beans:bean class="org.Apache.commons.dbcp.BasicDataSource" id="HSQL_DS">
<beans:property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<beans:property name="url" value="jdbc:hsqldb:mem:Test"/>
<beans:property name="username" value="sa"/>
<beans:property name="password" value=""/>
</beans:bean>
<jdbc:embedded-database id="HSQL_DS">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:data.sql"/>
</jdbc:embedded-database>
et ma classe de test ressemble à ceci:
public class Tester {
private EmbeddedDatabase db;
@Before
public void setUp(){
db = new EmbeddedDatabaseBuilder().addDefaultScripts().build();
}
@Test
public void TestMe(){
System.out.println("Testing");
}
@After
public void tearDown(){
db.shutdown();
}
}