views:

904

answers:

1

Hi there.

I've been following a tutorial and a sample application, namely 5 Days of Wicket - Writing the tests: http://www.mysticcoders.com/blog/2009/03/10/5-days-of-wicket-writing-the-tests/

I've set up my own little project with a simple shoutbox that saves messages to a database. I then wanted to set up a couple of tests that would make sure that if a message is stored in the database, the retrieved object would contain the exact same data.

Upon running mvn test all my tests fail. The exception has been pasted in the first code box underneath. I've noticed that even though my unitils.properties says to use the 'hdqldb'-dialect, this message is still output in the console window when starting the tests: INFO - Dialect - Using dialect: org.hibernate.dialect.PostgreSQLDialect. I've added the entire dump from the console as well at the bottom of this post (which goes on for miles and miles :-)).

Upon running mvn test all my tests fail, and the exception is:

Caused by: java.sql.SQLException: Table not found in statement [select relname from pg_class]
 at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
 at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
 at org.hsqldb.jdbc.jdbcStatement.executeQuery(Unknown Source)
 at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:188)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.initSequences(DatabaseMetadata.java:151)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.(DatabaseMetadata.java:69)
 at org.hibernate.tool.hbm2ddl.DatabaseMetadata.(DatabaseMetadata.java:62)
 at org.springframework.orm.hibernate3.LocalSessionFactoryBean$3.doInHibernate(LocalSessionFactoryBean.java:958)
 at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
 ... 49 more

I've set up my unitils.properties file like so:

database.driverClassName=org.hsqldb.jdbcDriver

database.url=jdbc:hsqldb:mem:PUBLIC
database.userName=sa
database.password=

database.dialect=hsqldb

database.schemaNames=PUBLIC

My abstract IntegrationTest class:

@SpringApplicationContext({"/com/upbeat/shoutbox/spring/applicationContext.xml", "applicationContext-test.xml"})
public abstract class AbstractIntegrationTest extends UnitilsJUnit4 {
 private ApplicationContext applicationContext;
}

applicationContext-test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
   <bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean"/>
</beans>

and finally, one of the test classes:

package com.upbeat.shoutbox.web;

import org.apache.wicket.spring.injection.annot.test.AnnotApplicationContextMock;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Test;
import org.unitils.spring.annotation.SpringBeanByType;

import com.upbeat.shoutbox.HomePage;
import com.upbeat.shoutbox.integrations.AbstractIntegrationTest;
import com.upbeat.shoutbox.persistence.ShoutItemDao;
import com.upbeat.shoutbox.services.ShoutService;

public class TestHomePage extends AbstractIntegrationTest
{
 @SpringBeanByType
 private ShoutService svc;

 @SpringBeanByType
 private ShoutItemDao dao;

 protected WicketTester tester;

 @Before
 public void setUp()
 {
  AnnotApplicationContextMock appctx = new AnnotApplicationContextMock();

  appctx.putBean("shoutItemDao", dao);
  appctx.putBean("shoutService", svc);
  tester = new WicketTester();
 }

 @Test
 public void testRenderMyPage()
 {
  //start and render the test page
  tester.startPage(HomePage.class);

  //assert rendered page class
  tester.assertRenderedPage(HomePage.class);

  //assert rendered label component
  tester.assertLabel("message", "If you see this message wicket is properly configured and running");
 }
}

Dump from console when running mvn test:

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building shoutbox
[INFO]    task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO] Copying 4 resources
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!
[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: F:\Projects\shoutbox\target\surefire-reports
INFO  - ConfigurationLoader        - Loaded main configuration file unitils-default.properties from classpath.
INFO  - ConfigurationLoader        - Loaded custom configuration file unitils.properties from classpath.
INFO  - ConfigurationLoader        - No local configuration file unitils-local.properties found.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.upbeat.shoutbox.web.TestViewShoutsPage
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.02 sec 
INFO  - Version                    - Hibernate Annotations 3.4.0.GA
INFO  - Environment                - Hibernate 3.3.0.SP1
INFO  - Environment                - hibernate.properties not found
INFO  - Environment                - Bytecode provider name : javassist
INFO  - Environment                - using JDK 1.4 java.sql.Timestamp handling
INFO  - Version                    - Hibernate Commons Annotations 3.1.0.GA
INFO  - AnnotationBinder           - Binding entity from annotated class: com.upbeat.shoutbox.models.ShoutItem
INFO  - QueryBinder                - Binding Named query: item.getById => from ShoutItem item where item.id = :id
INFO  - QueryBinder                - Binding Named query: item.find => from ShoutItem item order by item.timestamp desc
INFO  - QueryBinder                - Binding Named query: item.count => select count(item) from ShoutItem item
INFO  - EntityBinder               - Bind entity com.upbeat.shoutbox.models.ShoutItem on table SHOUT_ITEMS
INFO  - AnnotationConfiguration    - Hibernate Validator not found: ignoring
INFO  - notationSessionFactoryBean - Building new Hibernate SessionFactory
INFO  - earchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
INFO  - ConnectionProviderFactory  - Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
INFO  - SettingsFactory            - RDBMS: HSQL Database Engine, version: 1.8.0
INFO  - SettingsFactory            - JDBC driver: HSQL Database Engine Driver, version: 1.8.0
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - TransactionFactoryFactory  - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO  - actionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  - SettingsFactory            - Automatic flush during beforeCompletion(): disabled
INFO  - SettingsFactory            - Automatic session close at end of transaction: disabled
INFO  - SettingsFactory            - JDBC batch size: 1000
INFO  - SettingsFactory            - JDBC batch updates for versioned data: disabled
INFO  - SettingsFactory            - Scrollable result sets: enabled
INFO  - SettingsFactory            - JDBC3 getGeneratedKeys(): disabled
INFO  - SettingsFactory            - Connection release mode: auto
INFO  - SettingsFactory            - Default batch fetch size: 1
INFO  - SettingsFactory            - Generate SQL with comments: disabled
INFO  - SettingsFactory            - Order SQL updates by primary key: disabled
INFO  - SettingsFactory            - Order SQL inserts for batching: disabled
INFO  - SettingsFactory            - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO  - ASTQueryTranslatorFactory  - Using ASTQueryTranslatorFactory
INFO  - SettingsFactory            - Query language substitutions: {}
INFO  - SettingsFactory            - JPA-QL strict compliance: disabled
INFO  - SettingsFactory            - Second-level cache: enabled
INFO  - SettingsFactory            - Query cache: enabled
INFO  - SettingsFactory            - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
INFO  - FactoryCacheProviderBridge - Cache provider: org.hibernate.cache.HashtableCacheProvider
INFO  - SettingsFactory            - Optimize cache for minimal puts: disabled
INFO  - SettingsFactory            - Structured second-level cache entries: disabled
INFO  - SettingsFactory            - Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
INFO  - SettingsFactory            - Echoing all SQL to stdout
INFO  - SettingsFactory            - Statistics: disabled
INFO  - SettingsFactory            - Deleted entity synthetic identifier rollback: disabled
INFO  - SettingsFactory            - Default entity-mode: pojo
INFO  - SettingsFactory            - Named query checking : enabled
INFO  - SessionFactoryImpl         - building session factory
INFO  - essionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
INFO  - UpdateTimestampsCache      - starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
INFO  - StandardQueryCache         - starting query cache at region: org.hibernate.cache.StandardQueryCache
INFO  - notationSessionFactoryBean - Updating database schema for Hibernate SessionFactory
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO  - SQLErrorCodesFactory       - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
INFO  - DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3e0ebb: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
INFO  - sPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@a8e586: display name [org.springframework.context.support.ClassPathXmlApplicationContext@a8e586]; startup date [Tue May 04 18:19:58 CEST 2010]; root of context hierarchy
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [com/upbeat/shoutbox/spring/applicationContext.xml]
INFO  - XmlBeanDefinitionReader    - Loading XML bean definitions from class path resource [applicationContext-test.xml]
INFO  - DefaultListableBeanFactory - Overriding bean definition for bean 'dataSource': replacing [Generic bean: class [org.apache.commons.dbcp.BasicDataSource]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=close; defined in class path resource [com/upbeat/shoutbox/spring/applicationContext.xml]] with [Generic bean: class [org.unitils.database.UnitilsDataSourceFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext-test.xml]]
INFO  - sPathXmlApplicationContext - Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@a8e586]: org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1
INFO  - pertyPlaceholderConfigurer - Loading properties file from class path resource [application.properties]
INFO  - DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
INFO  - AnnotationBinder           - Binding entity from annotated class: com.upbeat.shoutbox.models.ShoutItem
INFO  - QueryBinder                - Binding Named query: item.getById => from ShoutItem item where item.id = :id
INFO  - QueryBinder                - Binding Named query: item.find => from ShoutItem item order by item.timestamp desc
INFO  - QueryBinder                - Binding Named query: item.count => select count(item) from ShoutItem item
INFO  - EntityBinder               - Bind entity com.upbeat.shoutbox.models.ShoutItem on table SHOUT_ITEMS
INFO  - AnnotationConfiguration    - Hibernate Validator not found: ignoring
INFO  - notationSessionFactoryBean - Building new Hibernate SessionFactory
INFO  - earchEventListenerRegister - Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
INFO  - ConnectionProviderFactory  - Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
INFO  - SettingsFactory            - RDBMS: HSQL Database Engine, version: 1.8.0
INFO  - SettingsFactory            - JDBC driver: HSQL Database Engine Driver, version: 1.8.0
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - TransactionFactoryFactory  - Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
INFO  - actionManagerLookupFactory - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO  - SettingsFactory            - Automatic flush during beforeCompletion(): disabled
INFO  - SettingsFactory            - Automatic session close at end of transaction: disabled
INFO  - SettingsFactory            - JDBC batch size: 1000
INFO  - SettingsFactory            - JDBC batch updates for versioned data: disabled
INFO  - SettingsFactory            - Scrollable result sets: enabled
INFO  - SettingsFactory            - JDBC3 getGeneratedKeys(): disabled
INFO  - SettingsFactory            - Connection release mode: auto
INFO  - SettingsFactory            - Default batch fetch size: 1
INFO  - SettingsFactory            - Generate SQL with comments: disabled
INFO  - SettingsFactory            - Order SQL updates by primary key: disabled
INFO  - SettingsFactory            - Order SQL inserts for batching: disabled
INFO  - SettingsFactory            - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO  - ASTQueryTranslatorFactory  - Using ASTQueryTranslatorFactory
INFO  - SettingsFactory            - Query language substitutions: {}
INFO  - SettingsFactory            - JPA-QL strict compliance: disabled
INFO  - SettingsFactory            - Second-level cache: enabled
INFO  - SettingsFactory            - Query cache: enabled
INFO  - SettingsFactory            - Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
INFO  - FactoryCacheProviderBridge - Cache provider: org.hibernate.cache.HashtableCacheProvider
INFO  - SettingsFactory            - Optimize cache for minimal puts: disabled
INFO  - SettingsFactory            - Structured second-level cache entries: disabled
INFO  - SettingsFactory            - Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
INFO  - SettingsFactory            - Echoing all SQL to stdout
INFO  - SettingsFactory            - Statistics: disabled
INFO  - SettingsFactory            - Deleted entity synthetic identifier rollback: disabled
INFO  - SettingsFactory            - Default entity-mode: pojo
INFO  - SettingsFactory            - Named query checking : enabled
INFO  - SessionFactoryImpl         - building session factory
INFO  - essionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
INFO  - UpdateTimestampsCache      - starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
INFO  - StandardQueryCache         - starting query cache at region: org.hibernate.cache.StandardQueryCache
INFO  - notationSessionFactoryBean - Updating database schema for Hibernate SessionFactory
INFO  - Dialect                    - Using dialect: org.hibernate.dialect.PostgreSQLDialect
INFO  - DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5dfaf1: defining beans [propertyConfigurer,dataSource,sessionFactory,shoutService,shoutItemDao,wicketApplication,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager]; root of factory hierarchy
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.34 sec <<< FAILURE!
Running com.upbeat.shoutbox.integrations.ShoutItemIntegrationTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0 sec <<< FAILURE!
Running com.upbeat.shoutbox.mocks.ShoutServiceTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.01 sec <<< FAILURE!

Results :

Tests in error: 
  initializationError(com.upbeat.shoutbox.web.TestViewShoutsPage)
  testRenderMyPage(com.upbeat.shoutbox.web.TestHomePage)
  initializationError(com.upbeat.shoutbox.integrations.ShoutItemIntegrationTest)
  initializationError(com.upbeat.shoutbox.mocks.ShoutServiceTest)

Tests run: 4, Failures: 0, Errors: 4, Skipped: 0

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

Please refer to F:\Projects\shoutbox\target\surefire-reports for the individual test results.
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Tue May 04 18:19:58 CEST 2010
[INFO] Final Memory: 13M/31M
[INFO] ------------------------------------------------------------------------

Any help is greatly appreciated.

+1  A: 

While applicationContext-test.xml overrides the default datasource to supply a Unitils datasource, the applicationContext.xml still declares the following property (that gets replaced during Maven filtering):

<prop key="hibernate.dialect">${hibernate.dialect}</prop>

So, if you want to run integration tests against an HSQLDB database (Unitils seems to be configured to do so), my understanding is that you are supposed to use the filter filters-LOCAL.properties that is triggered when using the LOCAL profile and declares:

hibernate.dialect=org.hibernate.dialect.HSQLDialect

You can check the target/classes/applicationContext.xml to confirm this but it seems obvious that you're not getting the above value but PostgreSQLDialect.

The odd part is that the pom.xml of mysticpaste declares the LOCAL profile as activeByDefault (at least the version in the project repository):

<profile>
  <id>LOCAL</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <properties>
    <env>LOCAL</env>
  </properties>
</profile> 

It should just work. So the question are:

  • what does mvn help:active-profiles say?
  • do you have the this LOCAL profile (and the LOCAL filter)?
  • do you have the latest version of this pom.xml?
Pascal Thivent
I have removed the filters that mysticpaste uses in their pom, so I'm not using it. I did this based on an earlier question where it was suggested that I keep away from using filters. Instead of these filters I'm using 1 single application.properties file (which contains "hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect").I'll create the LOCAL filter as you suggested with the appropriate HSQLDialect set :-)
John
The suggestion you received here on SO is just one opinion and doesn't necessarily reflect all opinions :) I personally share the point of view expressed by the author of this Wicket series in [this comment](http://www.mysticcoders.com/blog/2009/03/09/5-days-of-wicket-day-1/#comment-1313) and prefer profiles over `PropertyPlaceholderConfigurer`.
Pascal Thivent
Thanks a lot Pascal, for the help with the original problem and the note on the use of profiles. Your suggestion of making a profile with the appropriate dialect seems to have done the trick!
John
@John To be clear, using a profile to switch from one dialect to another is just one way to go, nothing forces you to use this solution (even if I think profiles are nice). But the fact is that you need to change the value of the `hibernate.dialect` property depending on the environment.
Pascal Thivent
@Pascal Using profiles seems like a clever choice as I do have several environments (development, testing, pre-production and production). When deploying to the production server, is it enough to use the -P parameter for the deploy command only, or would I need to set the profile containing my production settings to activeByDefault before sending it off to tomcat?
John
@John: Dealing with environments is indeed a perfect use case for profiles. Regarding your question, my recommendation would be to not change the `activeByDefault`, use this for the profile that you use the most frequently (very likely a development profile), don't change your pom to release to another environment. Instead, use `-P` when you want another profile (this will disable any profile active by default). Just in case, have a look at the [Introduction to Build Profiles](http://maven.apache.org/guides/introduction/introduction-to-profiles.html).
Pascal Thivent