简体   繁体   English

Spring / Hibernate / Junit测试DAO对HSQLDB的例子

[英]Spring/Hibernate/Junit example of testing DAO against HSQLDB

I'm working on trying to implement a JUnit test to check the functionality of a DAO. 我正在尝试实现一个JUnit测试来检查DAO的功能。 (The DAO will create/read a basic object/table relationship). (DAO将创建/读取基本对象/表关系)。

The trouble I'm having is the persistence of the DAO (for the non-test code) is being completed through an in-house solution using Spring/Hibernate , which eliminates the usual *.hbm.xml templates that most examples I have found contain. 我遇到的麻烦是DAO的持久性(对于非测试代码)是通过使用Spring / Hibernate的内部解决方案完成的,这消除了我发现的大多数示例的常见*.hbm.xml模板包含。

Because of this, I'm having some trouble understanding how to setup a JUnit test to implement the DAO to create/read (just very basic functionality) to an in-memory HSQLDB . 因此,我在理解如何设置JUnit测试以实现DAO来创建/读取(只是非常基本的功能)到内存中的HSQLDB时遇到了一些麻烦。 I have found a few examples, but the usage of the in-house persistence means I can't extend some of the classes the examples show (I can't seem to get the application-context.xml setup properly). 我找到了一些例子,但内部持久性的使用意味着我无法扩展示例所显示的一些类(我似乎无法正确设置application-context.xml)。

Can anyone suggest any projects/examples I could take a look at (or any documentation) to further my understanding of the best way to implement this test functionality? 任何人都可以建议我可以看一下(或任何文档)的任何项目/示例,以进一步理解实现此测试功能的最佳方法吗? I feel like this should be really simple, but I keep running into problems implementing the examples I have found. 我觉得这应该很简单,但是我在实现我发现的例子时遇到了问题。

edit: 编辑:

Here's my solution for better readability, for anyone who needs a hand getting things going: 这是我的解决方案,为了更好的可读性,对于任何需要帮忙的人来说:

  • My TestClass : 我的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; 
  • My applicationContext.xml file: 我的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 offers a new jdbc namespace that includes support for embedded databases, including HSQLDB. Spring 3提供了一个新的jdbc命名空间,其中包括对嵌入式数据库的支持,包括HSQLDB。 So that takes care of that part. 因此,照顾那一部分。

I'm wondering what the "in-house solution" could be. 我想知道“内部解决方案”是什么。 You can use annotations (either JPA or Hibernate annotations) to ORM your domain objects, so why do you need an "in-house solution"? 您可以使用注释(JPA或Hibernate注释)来ORM您的域对象,那么为什么需要“内部解决方案”? Eg: 例如:

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

As far as implementing a test goes, use Spring's TestContext Framework. 就实现测试而言,使用Spring的TestContext Framework。 A test can look like this (again I'm assuming Spring 3 below, though it should work in Spring 2.5 simply by changing @Inject to @Autowired): 测试可能看起来像这样(我再次假设下面是Spring 3,尽管只需将@Inject更改为@Autowired就可以在Spring 2.5中使用):

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

You'd put the embedded database inside beans-datasource-it.xml , for example. 例如,您将嵌入式数据库放在beans-datasource-it.xml ('it' here stands for integration test, and the files are on the classpath.) The controller in this example lives in beans-web.xml , and will be autowired into the ContactController field. ('它'代表集成测试,文件位于类路径上。)此示例中的控制器位于beans-web.xml ,并将自动装入ContactController字段。

That's just an outline of what to do but hopefully it's enough to get you started. 这只是一个如何做的概述,但希望它足以让你开始。

See here . 看到这里 It assumes maven2 as build tool, but you can easily use anything. 它假设maven2作为构建工具,但您可以轻松使用任何东西。

I have recently implemented a similar solution in some of my code using Hibernate , Spring and HSQLDB. 我最近在一些代码中使用HibernateSpringHSQLDB实现了类似的解决方案

Its is worth noting that AbstractTransactionalJUnit4SpringContextTests has now be deprecated - but it is still pretty straight forward to test - I cover most the details here: http://automateddeveloper.blogspot.com/2011/05/hibernate-spring-testing-dao-layer-with.html 值得注意的是,现在已经弃用了AbstractTransactionalJUnit4SpringContextTests - 但它仍然非常直接进行测试 - 我在这里详细介绍了大部分细节: http//automateddeveloper.blogspot.com/2011/05/hibernate-spring-testing-dao-层-with.html

The bottom line with hibernate is the SessionFactory - your in-house solution will most likely be creating one of these somehow. hibernate的底线是SessionFactory - 你的内部解决方案很可能会以某种方式创建其中一个。 Find out how, and then add a bean to create one in your test app context in the same way (or if possible using your in-house code that is used at runtime.). 了解如何,然后添加一个bean以相同的方式在测试应用程序上下文中创建一个bean(或者如果可能的话,使用在运行时使用的内部代码)。 You may need to create your own FactoryBean to do the instantiation. 您可能需要创建自己的FactoryBean来进行实例化。 (Use AbstractFactoryBean as your base class.) (使用AbstractFactoryBean作为基类。)

Once this is in place, most of the examples using LocalSessionFactoryBean can be migrated to your situation - instead of using LocalsessionFactoryBean, use your custom factory bean. 一旦这样,使用LocalSessionFactoryBean的大多数示例都可以迁移到您的情况 - 而不是使用LocalsessionFactoryBean,请使用您的自定义工厂bean。

(If you've not done so already, look at the Testing section in the spring reference - it makes testing with Spring, and injecting tests with beans from the context a breeze.) (如果你还没有这样做,请查看spring参考中的Testing部分 - 它使用Spring进行测试,并从上下文中轻松地使用bean注入测试。)

My application context looks a bit different 我的应用程序上下文看起来有点不同

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

and my test class looks like this: 我的测试类看起来像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM