Wednesday, January 27, 2010

Spring Testing with multiple data sources

Spring Testing with multiple data sources and errors:

We all are required to use multiple data sources connecting to different databases as part of our development. So, we tend to use different dataSource and declare them in our applicationContext.xml a.k.a. Spring Application Context configuration file.

Then, we also use Spring testing framework to test the functionality that we write. In most of the cases after Spring 2.5, we leverage upon use of AbstractAnnotationAwareTransactionalTests classes.

Error:

But, if we have defined multiple data sources / multiple persistance units in our application, these test cases fails. To be specific, the loading of application context fails, since it tries to find only one bean with type DataSource, but found multiple.

Unsatisfied dependency expressed through bean property 'dataSource': No unique bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: [dataSource,myCustomDataSource]; ...

Solution:

To solve such kind of issues, there is not clear documentation provided and one has to do lots of search over the internet. I've spent almost 2-3 hours today to solve such issue and the solution turns out to be pretty simple !!!

You just need to override some of the methods as shown below.


import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;

/**
* Base Test class for Services. It will be extended and used by all the Service Test
* classes.
*
* @author swapnil
*
*/
public class BaseServiceTest extends AbstractAnnotationAwareTransactionalTests
{
protected String [] getConfigLocations ()
{
return new String [] { "classpath:/myApplicationContext.xml" };
}

public void setDataSource (@Qualifier("myCustomDataSource")
DataSource dataSource)
{
super.setDataSource (dataSource);
}

public void setTransactionManager (@Qualifier("myCustomTransactionManager")
PlatformTransactionManager transactionManager)
{
super.setTransactionManager (transactionManager);
}

Sometimes, with lots of things cropping up in your brain, you try out various complex things, rather than think simple and try simple. Just an IDE checking override would have done ;)

No comments:

Post a Comment