2010-05-18 7 views
17

Ich arbeite an dem Versuch, einen JUnit Test zu implementieren, um die Funktionalität eines DAO zu überprüfen. (Das DAO erstellt/liest eine grundlegende Objekt/Tabellen-Beziehung).Spring/Hibernate/Junit Testbeispiel DAO gegen HSQLDB

Das Problem das ich habe, ist die Persistenz des DAO (für den Code nicht-Test) durch eine Inhouse-Lösung wird Frühjahr/Hibernate mit abgeschlossen, die die üblichen *.hbm.xml Vorlagen, die meisten Beispiele, die ich beseitigt habe gefunden.

Aus diesem Grunde, ich habe einige Schwierigkeiten zu verstehen, wie Setup einen JUnit Test, um die DAO zu implementieren/Lese erstellen (nur sehr grundlegende Funktionen) zu einem In-Memory-HSQLDB. Ich habe ein paar Beispiele gefunden, aber die Verwendung der internen Persistenz bedeutet, dass ich einige der Klassen, die die Beispiele zeigen, nicht erweitern kann (ich kann das Setup von application-context.xml nicht richtig bekommen).

Kann jemand irgendwelche Projekte/Beispiele vorschlagen, die ich mir (oder irgendeiner Dokumentation) ansehen könnte, um mein Verständnis der besten Art und Weise zu verbessern, diese Testfunktionalität zu implementieren? Ich denke, das sollte wirklich einfach sein, aber ich stoße immer wieder auf Probleme bei der Umsetzung der Beispiele, die ich gefunden habe.

edit:

Hier ist meine Lösung für eine bessere Lesbarkeit, für jeden, der eine Hand braucht, Dinge gehen:

  • Mein 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; 
    
  • Meine applicationContext.xml Datei :

+0

Einige zusätzliche Informationen: ich bin auch nicht mit dem Konfigu erfahren Ich habe sie bereits in früheren Projekten konfiguriert. Mein aktuelles Projekt ist ein Mischmasch von Konfigurationen, ich kann nicht herausfinden, wie die "in-house" -Klasse, auf die ich mich bezogen habe, ihre Sitzungsfabrik erhält. Alle DAOs erweitern es (eine abstrakte Klasse), und innerhalb ist eine abstrakte Deklaration: public abstract SessionFactory getSessionFactory(); Ich kann nicht herausfinden, wo die Methode "getSessionFactory()" herkommt. Ich denke, es muss irgendwie von Spring eingespielt werden, aber ich kann keine Konfigurationsdateien finden. –

+0

Danke Leute, ihr wart alle hilfreich. Für die in der Zukunft: Ich habe meine Unit applicationContext-Test.xml in meine Unit-Test (über @ContextConfiguration wie Willie spezifiziert) aufgenommen, in dem ich eine HSQLDB-Datenquelle, Sitzungsfabrik, Transaktionsmanager und das Daos als Bohnen . Meine Testklasse ist mit folgendem Kommentar versehen: @RunWith (SpringJUnit4ClassRunner.class), @ContextConfiguration (locations = "Ihre appContext.xml") @Transactional, und meine Sitzungsfactory & dao sind als Ressourcen annotiert (aus .xml defs): @ Ressource (name = "sessionFactory") –

Antwort

5

Spring 3 bietet einen neuen jdbc-Namespace mit Unterstützung für eingebettete Datenbanken, einschließlich HSQLDB. Das kümmert sich also um diesen Teil.

Ich frage mich, was die "Inhouse-Lösung" sein könnte. Sie können Anmerkungen (JPA- oder Hibernate-Annotationen) verwenden, um Ihre Domänenobjekte zu ORM zu machen. Warum benötigen Sie eine "Inhouse-Lösung"? Z.B.:

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" 
    p:dataSource-ref="dataSource" 
    p:packagesToScan="myapp.model" /> 

Sofern ein Test implementiert wird, verwenden Sie Spring TestContext Framework. Ein Test kann wie folgt aussehen (wieder Ich gehe davon aus Frühling 3 unten, obwohl es in Spring 2.5, indem einfach @Inject zu @Autowired funktionieren sollte):

@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 ... 
    } 
} 

Sie würden setzen die eingebettete Datenbank innerhalb beans-datasource-it.xml, beispielsweise. ("Es" steht hier für Integrationstest und die Dateien befinden sich im Klassenpfad.) Der Controller in diesem Beispiel lebt in beans-web.xml und wird automatisch in das Feld ContactController geleitet.

Das ist nur ein Überblick darüber, was zu tun ist, aber hoffentlich ist es genug, um loszulegen.

1

Unterm Strich mit Hibernate ist die SessionFactory - Ihre Inhouse-Lösung wird höchstwahrscheinlich eine dieser irgendwie erschaffen. Finden Sie heraus, wie und fügen Sie dann eine Bean hinzu, um eine in Ihrem Test-App-Kontext auf die gleiche Weise zu erstellen (oder wenn möglich mit Ihrem internen Code, der zur Laufzeit verwendet wird). Sie müssen möglicherweise Ihre eigene FactoryBean erstellen, um die Instanziierung durchzuführen. (Verwenden Sie AbstractFactoryBean als Ihre Basisklasse.)

Sobald diese vorhanden ist, können die meisten Beispiele, die LocalSessionFactoryBean verwenden, in Ihre Situation migriert werden. Verwenden Sie anstelle von LocalsessionFactoryBean Ihre benutzerdefinierte Factory-Bean.

(Wenn Sie dies noch nicht getan haben, sehen Sie den Testing Abschnitt im Frühjahr Referenz -. Es Tests mit Spring, und Injizieren Tests mit Bohnen aus dem Kontext eine Brise macht)

2

See here. Es nimmt maven2 als Build-Tool an, aber Sie können einfach alles verwenden.

+0

@ downvoter - war es, weil ich mit meinem Blog verbunden? – Bozho

0

Mein Anwendungskontext ein bisschen anders aussieht

<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> 

und meine Test-Klasse sieht wie folgt aus:

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(); 
    } 
}