Life as Code

refactoring my life

Archive for the ‘Spring Framework’ Category

Transactional unit tests that support scopes using JUnit and Spring

with one comment

Most of the unit tests that you write don’t need support for transactions and scopes, but if you ever want to test your web frontend code properly you’ll hit into this one.

Writing transactional unit test with JUnit, Spring and Hibernate is easy, what you want to do is:

- Add a transaction management bean in your test context:

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>

- Make your test extend AbstractTransactionalJUnit4SpringContextTests
- Annotate you test class with @TransactionConfiguration and @Transactional

If your transaction demarcation is correct( surrounding your dao or service ) you should be done. This is the cleanest way that I found.

Everything until now is fine and dandy. The problem arises when one of the injected beans is bound to a scope. It can be any scope but for this example I’ll take the simplest scope – the ‘session’ scope.

In a non-transactional situation this should be pretty straight forward, just implement Scope and using a ConfigurableBeanFactory register it. The fact that we are extending <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.html"AbstractTransactionalJUnit4SpringContextTests and that our context is automatically created really kills the simple path.

You’ll get a org.springframework.beans.factory.BeanCreationException with a nested “java.lang.IllegalStateException: No Scope registered for scope ‘session’”.

But do not despair, there is simple solution available and it’s called CustomScopeConfigurer.

The fastest and cleanest way to use it is:
- Create a simple class that will be used as our scope manager. Let’s call it MockSessionScope.

code

- In your test context, create a CustomScopeConfigurer that will automatically register your scope on context creation:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="com.gridpulse.xandria.translator.MockSessionScope"/>
</entry>
</map>
</property>
</bean>

Run your tests and you’re done!

Written by Bogdan

August 21, 2009 at 4:45 PM

Using Spring 2.0′s WebAppRootListener to access your web application root

leave a comment »

Spring 2.0 includes a special ServletContextListener implementation that can save you a lot of time and get you out of trouble when developing Spring-enabled Java web applications.

What does WebAppRootListener offer?

Well, not that much. WebAppRootListener just sets a system property that points to your web application root, making it available for your never-ending pleasure, enabling you to not hardcode the webapp root or write mangling code to find it.
Really, it’s a lifesaver sometimes.

How can I use it?

First, some info that you don’t find that often:
Some web containers and application servers don’t isolate web applications, which can cause property (and a lot of other) clashes. Tomcat doesn’t while Resin for example does.
If you want to use WebAppRootListener in multiple web applications running on the same Tomcat instance, read the webAppRootKey section. I recommend doing this regardless.

The first step in enabling your WebAppRootListener is adding it to web xml.

You do this by adding a new listener to your web.xml with listener-class set to org.springframework.web.util.WebAppRootListener.

<listener>
<listener-class>
org.springframework.web.util.WebAppRootListener
</listener-class>
</listener>

After adding the listener, you must add a PPC (PropertyPlaceholderConfigurer) to access system properties to your application context.


<bean id="systemPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

This step just enabled the use of your web app root inside your application context, just by using ${webapp.root} in your properties. Example from a velocityConfig bean:


<prop key="file.resource.loader.path">${webapp.root}/WEB-INF/velocity</prop>

The webapp root is available inside bean properties as ${webapp.root} and inside Java code as System.getProperty(“webapp.root”);.

What is webAppRootKey?

If you want to use this in Tomcat, in multiple web applications, you must redefine the key by using a special context-param called webAppRootKey.
To do this, in each webapp, in your web.xml you must use webAppRootKey, to define a new name for the webapp.root key.

Example:

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myWebApp.root</param-value>
</context-param>

Now, the webapp root is available inside bean properties as ${myWebApp.root} and inside Java code as System.getProperty(“myWebApp.root”);.

Happy web application coding!

Written by Bogdan

November 3, 2007 at 10:36 AM

Follow

Get every new post delivered to your Inbox.

Join 259 other followers