我有一系列集成测试,我想用它们来测试我的 spring-mvc/spring-data-jpa 堆栈。不幸的是,构建时间是荒谬的,而且每次新的集成测试只会变得更糟。看起来好像每个单独的测试都在通过创建嵌入式数据库、创建 bean 等的开销。
我有一个基础测试类:
@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 );
}
我的 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>
}
最后我尝试使用它,例如:
@TransactionConfiguration( defaultRollback = true )
@Transactional( propagation = Propagation.NESTED )
public class TestContactTypesIT extends BaseItegration {
@Autowired
private ContactTypeRefRepository contactTypeRepository;
@Test
public void testRepositoryNotNull() {
Assert.assertNotNull( contactTypeRepository );
}
...}
在查看构建日志时,我可以看到每个测试的应用程序正在初始化。有没有办法让 BaseIntegrationTest 只启动一个和每个测试以使用该应用程序上下文和嵌入式数据库?
========
更新
我将我的 JpaConfig 更改为:
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType( EmbeddedDatabaseType.H2 ).setName( "mydb" )
.addScript( "classpath:embeddedDatabase.sql" ).build();
}
我的 BaseIntegration 现在是空的:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( loader = AnnotationConfigContextLoader.class, classes = { JpaConfig.class } )
public abstract class BaseItegration {
}
这是因错误而失败的测试之一:
InvalidDataAccessResourceUsageException(未找到表“ADDRESSTYPEREF”;SQL 语句:
@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() );
}
}
但是,所有集成测试似乎都重新创建了 applicationContext 和嵌入式数据库。虽然构建日志没有显示正在创建的数据源,但我确实看到每个集成测试都会创建一个新的 log4j 文件,并且构建 45 个测试需要 15 分钟。