I have a series of integration-tests that I want to test my spring-mvc/spring-data-jpa stack with. Unfortunately the build time is ridiculous and only getting worse with each new integration tests. It looks as if each separate test is going thru the overhead of creating an embedded database, bean creation etc.
I have a base test class:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( loader = AnnotationConfigContextLoader.class, classes = { JpaConfig.class } )
public class BaseItegration {
private static EmbeddedDatabase database;
@BeforeClass
public static void setUp() throws Exception {
database = new EmbeddedDatabaseBuilder().setType( EmbeddedDatabaseType.H2 ).setName( "mydb" )
.addScript( "classpath:embeddedDatabase.sql" ).build();
}
@Test
public void testInit() {
Assert.assertNotNull( database );
}
Where my JpaConfig.java :
@Configuration
@EnableTransactionManagement
@ComponentScan( basePackages = { "org.myproject.service", "org.myproject.utility",
"org.myproject.controller", "org.myproject.utility.startup",
"org.myproject.security" } )
@ImportResource( { "classpath:applicationContext.xml", "classpath:myproject-spring-security.xml" } )
public class JpaConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {...}
@Bean
public DataSource dataSource() {...}
<etc>
}
And then finally I try and use it such as:
@TransactionConfiguration( defaultRollback = true )
@Transactional( propagation = Propagation.NESTED )
public class TestContactTypesIT extends BaseItegration {
@Autowired
private ContactTypeRefRepository contactTypeRepository;
@Test
public void testRepositoryNotNull() {
Assert.assertNotNull( contactTypeRepository );
}
...}
When watching the build log, I can see the application init'ing for each test. Is there a way to get the BaseIntegrationTest to only startup one and each test to use that application context and embeddeddatabase?
========
Update
I changed my JpaConfig to this:
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType( EmbeddedDatabaseType.H2 ).setName( "mydb" )
.addScript( "classpath:embeddedDatabase.sql" ).build();
}
and my BaseIntegration now is empty:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( loader = AnnotationConfigContextLoader.class, classes = { JpaConfig.class } )
public abstract class BaseItegration {
}
here is one of the tests that is failing with the error:
InvalidDataAccessResourceUsageException (Table "ADDRESSTYPEREF" not found; SQL statement:
@TransactionConfiguration( defaultRollback = true )
@Transactional( propagation = Propagation.NESTED )
public class TestSeedAddressTypesIT extends BaseItegration {
@Autowired
private AddressTypeRefRepository addressTypeRepository;
@Autowired
private SeedAddressTypes seedAddressTypes;
// hack because we can't do a BeforeClass with Autowired
private boolean seeded = false;
@Test
public void testRepositoryNotNull() {
Assert.assertNotNull( addressTypeRepository );
}
@Test
public void testPopulatedDB() {
if (!seeded) {
seedAddressTypes.seed();
seeded = true;
}
List<AddressTypeRef> addressTypes = addressTypeRepository.findAll();
Assert.assertEquals( 5, addressTypes.size() );
}
}
However, all integration tests seem to recreate the applicationContext and embedded database. While the build log does not show the datasource being created, I do see each integration test creates a new log4j file, and 45 tests take 15 minutes to build.