4

I have a unit test that is run with SpringJUnit4ClassRunner as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:aConfig.xml")
public class TestService
{
     @Resource
     EmbeddedMysqlDatabase mysqlDB;

     ...
}

I have an embedded database that used in the unit tests that I would like to shutdown after all test have been run. I know embedding a database in a unit test is not usual/good practice but in this particular case this is super useful.

@AfterClass is not an option because it has to be static and my database instance is injected by spring. Static members cannot be injected.

How can i do that through a listener or any other means?

Thx.

7
  • I don't think that listener would be a good choice because you would have troubles running the test in the same way both from Build Tool's (Gradle, Maven, Ant) and IDE (IntelliJ, Eclipse, etc.). Also using embedded databases gives you a lot of nice choices when testing your code (provided you use the same database in both embeeded and runtime environment). Commented Jan 18, 2015 at 18:39
  • Thx. So what would you suggest for cleaning up the DB instance? Commented Jan 18, 2015 at 18:44
  • Since it is an embedded DB, won't it just be cleared automatically when the Spring Context is destroyed or overwritten on the next creation? Which DB do you want to use in embedded mode? Commented Jan 18, 2015 at 18:47
  • oh, do you mean using something like the detroy-method? Commented Jan 18, 2015 at 18:53
  • Thx. I managed to do using the destroy-method of the DB bean and it worked perfectly. Commented Jan 18, 2015 at 18:56

2 Answers 2

8

You can use @TestExecutionListeners. Something like this:

public class ShutdownExecutionListener extends AbstractTestExecutionListener {
    @Override 
    public void beforeTestClass(TestContext testContext) throwsException {
    }      
    @Override 
    public void afterTestClass(TestContext testContext) throws Exception{
        EmbeddedMysqlDatabase mysqlDB= 
            (EmbeddedMysqlDatabase)testContext.getApplicationContext().getBean(mysqlDB);
        mysqlDB.shutdown();     
    } 
}

And in your test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:aConfig.xml")
@TestExecutionListeners(listeners = ShutdownExecutionListener.class)
public class TestService
{
     @Resource
     EmbeddedMysqlDatabase mysqlDB;

     ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Antonio, and how is that different from using BeforeClass / AfterClass annotations?
R4J: i guess the difference is that it has the testContext which allow to access a bean unlike the @AfterClass that is static. In my particular use case though IMO the destroy-method technique is cleaner.
1

Works great, but don't forget to set "mergeMode"

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:aConfig.xml")
@TestExecutionListeners(listeners = {ShutdownExecutionListener.class}, 
                        mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
public class TestService
{
    @Resource
    EmbeddedMysqlDatabase mysqlDB;
    ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.