当前位置: 动力学知识库 > 问答 > 编程问答 >

hibernate - How to test DAO layer in tapestry dependent projects

问题描述:

I have a tapestry5 + hibernate application for which i am trying to write unit tests. I am looking for some guidance or best practices to test DAO layer in these kind of projects.

I tried below test case using testng but it didn't work.

@Test

public void createOrderTest() {

IOCUtilities.buildDefaultRegistry();

OrderManager orderManager = new OrderManager();

Order o1 = new Order();

Date date = new Date(System.currentTimeMillis());

o1.setOrderDate(date);

o1.setOrderStatus(OrderStatus.BILLED.toString());

orderManager.createOrder(o1);

}

Getting error message when i try to run the test case.

java.lang.IllegalArgumentException: Contribution org.apache.tapestry5.yuicompressor.services.YuiCompressorModule.contributeMinimizers(MappedConfiguration) (at YuiCompressorModule.java:42) is for service 'interface org.apache.tapestry5.services.assets.ResourceMinimizer' qualified with marker annotations [interface org.apache.tapestry5.ioc.annotations.Primary], which does not exist.

at org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:246)

at org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:205)

at org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:177)

at org.apache.tapestry5.ioc.IOCUtilities.buildDefaultRegistry(IOCUtilities.java:51)

at com.vc.xpressor.testng.OrderManagerTest.createOrderTest(OrderManagerTest.java:21)

网友答案:

If you use constructor injection in your DAO's, you don't need tapestry at all in your DAO tests. Am I correct that the only dependencies required by your DAO'S are the hibernate session and maybe a couple of @Symbols?

If so, all you need is to setup a connection to an in memory database (eg h2) and to wrap that in a hibernate session. Then pass the hibernate session to your DAO constructors.

I use a base test class for my DAO's which sets up the connection and session in a @Before method

Here's a sample DAO

public class ItemDAOImpl implements ItemDAO {
    private final Session session;

    public ItemDAOImpl(Session session) {
        this.session = session;
    }

    public List<Item> findAll() {
        return session.createCriteria(Item.class).list();
    }

    ....
}

In Tapestry, this is declared in the AppModule

public static void bind(ServiceBinder binder) {
    binder.bind(ItemDAO.class, ItemDAOImpl.class);
}

But in my test case, I don't need Tapestry

public class ItemDAOImplTest extends AbstractHibernateTest {
    private ItemDAO itemDAO;

    @Override
    protected void before() {
        itemDAO = new ItemDAOImpl(session);
    }

    @Override
    protected void after() {}

    @Test
    public void testFindAll() {
        session.save(new Item(...));
        session.save(new Item(...));
        session.save(new Item(...));
        assertEquals(3, itemDAO.findAll().size());
    }
}

public abstract class AbstractHibernateTest {
    protected SessionFactory sessionFactory;
    protected Session session;

    @Before
    public void abstractBefore() throws Exception {
        Configuration config = new Configuration();

        // see PackageNameHibernateConfigurer source code to dynamically add all
        // classes in the entities package
        config.addAnnotatedClass(Item.class);
        config.addAnnotatedClass(...);

        config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
        config.setProperty("hibernate.connection.url", "jdbc:h2:mem:test");
        config.setProperty("hibernate.hbm2ddl.auto", "create");
        config.setProperty("hibernate.show_sql", "true");
        config.setProperty("hibernate.format_sql", "true");

        sessionFactory = config.buildSessionFactory();
        session = sessionFactory.openSession();
        session.beginTransaction();
        before();
    }

    protected abstract void before() throws Exception;

    @After
    public void abstractAfter() throws Exception {
        Exception exception = null;
        try {
            after();
        } catch (Exception e) {
            exception = e;
        }

        session.getTransaction().rollback();
        session.close();
        sessionFactory.close();

        if (exception != null) {
            throw exception;
        }
    }

    protected abstract void after() throws Exception;
}
网友答案:

Another option, if you want to run the DAOs via the IoC is to separate your AppModule into two: one module that exists to define Hibernate entities and DAOs, and the rest in AppModule. You can initialize your tests using the DAOModule and the HibernateCoreModule (if you notice, Tapestry's Hibernate support is likewise split in two: a non-visual part that works on top of tapestry-ioc, and a visual part that provides additional hooks into tapestry-core).

分享给朋友:
您可能感兴趣的文章:
随机阅读: