views:

1225

answers:

5

I'm using the Spring transactional test classes to do unit testing of my DAO code. What I want to do is create my database once, before all the tests run. I have a @BeforeClass annotated method but that runs before Spring loads up the application context and configures the jdbcTemplate, thus I don't actually have a connection to the DB at that time. Is there a way to run my DB setup once after the context loads but before the tests start running?

This thead asks the same question but the accepted solution seems to just be "don't do that". I'm inclined to say this just seems like it isn't doable.

A: 

Try using your old methods instead of the fancy annotations.

@BeforeClass
    public static void beforeClass() {
     ApplicationContext context = new ClassPathXmlApplicationContext(
     "applicationContext.xml");
                  [...]
    }
Martin Dale Lyness
A: 

I don't know what unit testing framework you are using but for JUnit, you can make your test class subclass AbstractTransactionalJUnit4SpringContextTests which has an executeSqlScript method this can either be run in a beforeclass or beforemethod method. My preference is to use BeforeMethod as this means that each of my unit tests are autonomous, even if it means my unit tests run a bit slower.

mR_fr0g
I wouldn't be able to put this in a @BeforeClass method because @BeforeClass methods must be static and are run before the application context is loaded.
Adam B
Ok, it is possible with TestNg if that is any help?
mR_fr0g
A: 

I'd second the advice that you should make each of your tests autonomous and therefore do all your setup with @Before rather than with @BeforeClass.

If you wish to stick with your approach just use the @Before method and have a simple boolean check to see if the setup has already been completed. e.g.

 if(!databaseSetup) {
    ...set up the database
    databaseSetup=true;
    }

Not too fancy but it will work!

See my answer here for an example spring transaction test with annotations using dbunit.

Hope this helps!

Pablojim
-1 because in fact this will NOT work because JUnit creates an instance of the test class for every method, thus your "databaseSetup" variable will always be false when entering the "@Before" method and you will still end up reinitializing the database before every test method.
HDave
That's true - thanks for pointing it out. I suppose you could use a static member variable but that's just getting deeper into the problem.
Pablojim
+1  A: 
Michael Lange
A: 

I've extended my testclass from AbstractTransactionalJUnit4SpringContextTests.

In my testclass I've coded for testing purposes:

@BeforeClass
public static void myBeforeClassMethod(){
  System.out.println("BeforeClass executed");
}

Looking at the console output it seems that this method is indeed called BEFORE the spring applicationcontext is transparently loaded by the Spring Testcontext framework.

This is in fact too early because I want to use this method to populate my database with testdata (using e.g. Dbunit dataset) before Spring/JUnit starts executing the test methods. But in order to populate my database, the schema has to be created and that only happens while loading the applicationcontext when the Hibernate sessionfactory is initialized and the schema is created using hibernate's create schema property.

Given the above, how can I ensure that the application context is loaded and Hibernate created the schema, before this method is called ?

Thanks.

EDH
Better post this as a new question ("Ask Question" button in the top right of the page). That way more people will see it and you are more likely to get answers.
sth