5

In my spring + maven app, I have created some tests for the Data Access Layer that I would like now to run against multiple datasources. I have something like:

@ContextConfiguration(locations={"file:src/test/resources/testAppConfigMysql.xml"})
public class TestFooDao extends AbstractTransactionalJUnit38SpringContextTests {
  public void testFoo(){
     ...
  }
} 

It has currently the config location hardcoded, so it can be used only against one datasource. What is the best way to invoke the test twice and pass two different configs (say testAppConfigMysql.xml and testMyConfigHsqlDb.xml)?

I've seen suggestions to do this via system properties. How can I tell maven to invoke the tests twice, with different values of a system property?

jfu
  • 71
  • 3

3 Answers3

1

I don't know if there is some sexy and fancy solution, being simple as well, for this. I would just implement base class with all testing stuff and then inherit it into 2 classes with different annotation-based configuration, like this:

@ContextConfiguration(locations={"firstDs.xml"})
public class TestFooDaoUsingFirstDs extends TestFooDao {
}

@ContextConfiguration(locations={"secondDs.xml"})
public class TestFooDaoUsingSecondDs extends TestFooDao {
}

Unless you have to handle really high number of different datasources this way, that is OK for me.

Michał Kalinowski
  • 16,925
  • 5
  • 35
  • 48
  • But I have many daos Foo, Bar, ... (about 15 of them) and thus 15 test classes TestFooDao, TestBarDao,... in your solution I'd have to double the number of classes, which I do not want (I don't want also to merge all tests into one huge class) – jfu Apr 27 '12 at 10:02
  • Yeah, I know. But I really don't see any better solution. As I said, I'm completely aware this solution isn't perfect and sucks a little bit. Other thing that just came to my mind is try to use some kind of mix of JUnit's Theories with Spring imperative support for context configuration. That means you drop annotation-based config of Spring context and try to somehow setup it by calling some method. I don't know however Spring API good enought to give you some reference or example here. I'm not sure if it's really possible and works OK, but I just though about it. – Michał Kalinowski Apr 30 '12 at 09:39
  • Another idea: probably extending a little bit Spring Testing Support classes (like `SpringJUnit4ClassRunner` or some helpers around it) would solve the case, if there is no really out-of-the-box solution. In my opinion, you can override piece of code that handle `@ContextConfiguration` annotation and try to implement there own logic, probably using kind of custom annotation which accept parameter pointing multiple contexts. – Michał Kalinowski Apr 30 '12 at 13:10
0

Rather than file:..., you can use classpath:... (remove the src/test/resources, it's implicit if you use classpath). Then you can have a single master context with the line:

<import resource="dao-${datasource}.xml" />

If you run the Maven build with the option -Ddatasource=foo, it will replace the ${datasource} in the master context with the whatever you specify. So you can have datasource-foo.xml, datasource-bar.xml etc. for your different configurations.

(You need to enable Maven resource filtering in the POM for this to work).

Alternatively, check out the new stuff in Spring 3.1: http://www.baeldung.com/2012/03/12/project-configuration-with-spring/

Edit: A third option would be to have all the test classes extend some superclass, and use Junit's @Parameterised, where the parameters are the different Spring contexts. You couldn't use @ContextConfiguration in that case, but you can always create the Spring context manually, then autowire the test class using org.springframework.beans.factory.config.AutowireCapableBeanFactory.autowireBean()

artbristol
  • 32,010
  • 5
  • 70
  • 103
  • I'd like to run maven once and get both datasources tested; in your solution I need to run it twice, passing two values of the datasource variable. Is it possible to set set the variable within the maven surefire plugin (e.g. define two executions or some such)? The goal is to get both datasources tested when running mvn test – jfu Apr 27 '12 at 10:37
  • Yeah, that is a bit of a pain. I've not had much luck running the failsafe/surefire plugins more than once - they tend to get confused about output folders and the like. – artbristol Apr 27 '12 at 10:38
0

Check maven invoker plugin. It supports profiles also.

zaletniy
  • 549
  • 4
  • 12