Announcement Announcement Module
Collapse
No announcement yet.
Testing Business Objects Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Testing Business Objects

    'lo all,

    Newbie question:

    I seek endorsement on the my approach to testing my business objects and also to ask how I should implement business object validation. I have domain object validation but I need validation for each business object method according the functionality of each method.

    First here is the business object under test:
    Code:
    public class AccountManager {
      
      private static final Log log = LogFactory.getLog(AccountManager.class);
      
      private AccountDao accountDao = null;
      
      public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
      }
    
      
      public void createMerchant(MerchantVO vo) {
          // TODO validate vo - HOW?
          accountDao.create(vo);
      }
      
      public MerchantVO loadMerchant(long id) {
        return (MerchantVO)accountDao.load(id, MerchantVO.class);
      }
      
      public void saveMerchant(MerchantVO vo) {
        accountDao.persist(vo);
      }
    
      public void deleteMerchantVO(MerchantVO vo) {
        accountDao.delete(vo);
      }
    
      public void createCustomer(CustomerVO vo) {
        accountDao.create(vo);
      }
      
      public CustomerVO loadCustomer(long id) {
        return (CustomerVO) accountDao.load(id, CustomerVO.class);
      }
      
      //
    
      public void createCustomerAccount(CustomerAccountVO customerAccount) {
        accountDao.createCustomerAccount(customerAccount);
      }
    
      public void createIsp(IspVO vo) {
          accountDao.create(vo);
      }
      
      // TODO finish
    
    }
    Now here is the test case:

    Code:
    public class AccountManagerTest extends TestCase {
    
      /*
       * Test method for 'com.tll.biz.AccountManager.createMerchant(MerchantVO)'
       */
      public void testCreateMerchant() {
        
        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
            new String[] {"spring-db-hibernate.xml", "spring-biz.xml"});
        BeanFactory factory = (BeanFactory) appContext;
        
        AccountDao accountDao = (AccountDao)factory.getBean("myAccountDao");
        assertNotNull(accountDao);
        
        AccountManager accountManager = (AccountManager)factory.getBean("accountManager");
        assertNotNull(accountManager);
        
        MerchantVO mvo = (MerchantVO) accountDao.load(4, MerchantVO.class);
        accountManager.createMerchant(mvo);
      }
      
      // TODO finish test methods
    
    }
    Here are my spring xml config files:

    spring-db-hibernate.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE beans 
      PUBLIC "-//SPRING//DTD BEAN//EN" 
      "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
      
    	<!-- Configurer that replaces $&#123;...&#125; placeholders with values from a properties file -->
    	<!-- &#40;in this case, JDBC-related settings for the dataSource definition below&#41; -->
    	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location" value="file&#58;build.properties"/>
    	</bean>
      
      <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="$&#123;database.driver.classname&#125;"/>
        <property name="url" value="$&#123;database.url&#125;"/>
        <property name="username" value="$&#123;database.userid&#125;"/>
        <property name="password" value="$&#123;database.password&#125;"/>
      </bean>
      
      <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="hibernateProperties">
          <props>
            <prop key="default-lazy">false</prop>
            <prop key="hibernate.dialect">$&#123;hibernate.dialect&#125;</prop>
            <!--<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>-->
            <!--<prop key="hibernate.show_sql">true</prop>-->
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.generate_statistics">true</prop>
          </props>
        </property>
        <property name="mappingResources">
          <list>
            <value>com/tll/vo/AccountVO.hbm.xml</value>
            <value>com/tll/vo/AccountAddressVO.hbm.xml</value>
            <value>com/tll/vo/AccountHistoryVO.hbm.xml</value>
            <value>com/tll/vo/AccountUserVO.hbm.xml</value>
            <value>com/tll/vo/AddressVO.hbm.xml</value>
            <value>com/tll/vo/AspVO.hbm.xml</value>
            <value>com/tll/vo/CurrencyVO.hbm.xml</value>
            <value>com/tll/vo/CustomerVO.hbm.xml</value>
            <value>com/tll/vo/CustomerAccountVO.hbm.xml</value>
            <value>com/tll/vo/InterfaceVO.hbm.xml</value>
            <value>com/tll/vo/InterfaceAccountVO.hbm.xml</value>
            <value>com/tll/vo/IspVO.hbm.xml</value>
            <value>com/tll/vo/MerchantVO.hbm.xml</value>
            <value>com/tll/vo/OrderVO.hbm.xml</value>
            <value>com/tll/vo/OrderItemVO.hbm.xml</value>
            <value>com/tll/vo/OrderItemTransVO.hbm.xml</value>
            <value>com/tll/vo/OrderTransVO.hbm.xml</value>
            <value>com/tll/vo/PaymentInfoVO.hbm.xml</value>
            <value>com/tll/vo/PaymentTransVO.hbm.xml</value>
            <value>com/tll/vo/ProdCatVO.hbm.xml</value>
            <value>com/tll/vo/ProductCategoryVO.hbm.xml</value>
            <value>com/tll/vo/ProductCategoryHierarchyVO.hbm.xml</value>
            <value>com/tll/vo/ProductGeneralVO.hbm.xml</value>
            <value>com/tll/vo/ProductInventoryVO.hbm.xml</value>
            <value>com/tll/vo/SalesTaxVO.hbm.xml</value>
            <value>com/tll/vo/ShipBoundCostVO.hbm.xml</value>
            <value>com/tll/vo/ShipModeVO.hbm.xml</value>
            <value>com/tll/vo/ShopperVO.hbm.xml</value>
            <value>com/tll/vo/SiteCodeVO.hbm.xml</value>
          </list>
        </property>
      </bean>
      
    	<!-- Transaction manager for a single Hibernate SessionFactory &#40;alternative to JTA&#41; -->
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="mySessionFactory"/>
    	</bean>
    
      <!-- DAO beans -->
      <bean id="myAccountAddressDao" class="com.tll.dao.hibernate.HibernateAccountAddressDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myAccountDao" class="com.tll.dao.hibernate.HibernateAccountDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
        <property name="aspId" value="1"/>
      </bean>
      <bean id="myAccountHistoryDao" class="com.tll.dao.hibernate.HibernateAccountHistoryDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myAccountUserDao" class="com.tll.dao.hibernate.HibernateAccountUserDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myAddressDao" class="com.tll.dao.hibernate.HibernateAddressDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myCurrencyDao" class="com.tll.dao.hibernate.HibernateCurrencyDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myInterfaceAccountDao" class="com.tll.dao.hibernate.HibernateInterfaceAccountDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myInterfaceDao" class="com.tll.dao.hibernate.HibernateInterfaceDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myOrderDao" class="com.tll.dao.hibernate.HibernateOrderDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myPaymentInfoDao" class="com.tll.dao.hibernate.HibernatePaymentInfoDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myPaymentTransDao" class="com.tll.dao.hibernate.HibernatePaymentTransDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myProductDao" class="com.tll.dao.hibernate.HibernateProductDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="mySalesTaxDao" class="com.tll.dao.hibernate.HibernateSalesTaxDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myShipDao" class="com.tll.dao.hibernate.HibernateShipDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myShopperDao" class="com.tll.dao.hibernate.HibernateShopperDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="mySiteCodeDao" class="com.tll.dao.hibernate.HibernateSiteCodeDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <bean id="myValueObjectDao" class="com.tll.dao.hibernate.HibernateValueObjectDao">
        <property name="sessionFactory">
          <ref bean="mySessionFactory"/>
        </property>
      </bean>
      <!-- END DAO beans -->
      
    </beans>
    spring-biz.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE beans 
      PUBLIC "-//SPRING//DTD BEAN//EN" 
      "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
      
      <bean id="accountManagerTarget" class="com.tll.biz.AccountManager">
        <property name="accountDao" ref="myAccountDao"/>
        <property name="assemblerManager" ref="myAssemblerManager"/>
      </bean>
      
      <bean id="accountManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="transactionManager"/>
    		<property name="target" ref="accountManagerTarget"/>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="add*">PROPAGATION_REQUIRED</prop>
    				<prop key="save*">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
      
    </beans>
    Should my test cases for business objects be based on JUnit base class OR based on Spring's AbstractDependencyInjectionSpringContextTests class?

    And how sould I implement business object method level validation? How would I gain access to the Errors interface to put resultant error messages into from a bussiness object method vantage point? There seems to be no "nitty gritty" examples to illustrate this. JPetStore is way too simplified to provide meaningful help.

    Thanks for any advice.

    jpk
    jopaki@gmail

  • #2
    Should my test cases for business objects be based on JUnit base class OR based on Spring's AbstractDependencyInjectionSpringContextTests class?
    Depends on whether you want to do Unit testing or integration testing.

    You should probably test as much as you can with Unit tests - these isolate the component under test, and are much quicker as you don't have to read in the XML files (collaborators can be mocked).

    For integration testing, AbstractDependencyInjectionSpringContextTests is a good choice.

    Comment


    • #3
      +10 for katentims answer.

      One of the coolest things (IMO) is the fact that spring actively encourages POJOs and collaborators. If all your collaborators are implementing interfaces then unit testing becomes an absolute doddle and *almost* removes the need for integration testing

      Comment

      Working...
      X