我有这样的配置类:
@ComponentScan(
basePackages = {
"mypackage.controller",
"mypackage.service",
"mypackage.repository"
}
)
@TestPropertySource(locations="classpath:configuration.properties")
@Import({
H2Configuration.class
})
public class TestConfiguration {
}
@Configuration
public class H2Configuration {
@Bean
public DataSource dataSource() throws SQLException {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder
.setType(EmbeddedDatabaseType.H2)
.addScript("h2/create.sql")
.addScript("h2/insert.sql")
.build();
db.getConnection().setAutoCommit(false);
return db;
}
}
我有这两类测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes = { TestConfiguration.class })
public class FirstRepositoryTest {
@Autowired
MyFirstRepositoryImpl repository;
@Before
public void initTest() {
}
@Test(expected = NullPointerException.class)
public void testNullRecords() {
repository.foo(null, null);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes = { TestConfiguration.class })
public class SecondRepositoryTest {
@Autowired
MySecondRepositoryImpl repository;
@Before
public void initTest() {
}
@Test(expected = NullPointerException.class)
public void testSomethingNullRecords() {
repository.something(null, null);
}
}
如果我为每个类运行JUnit测试一次,一切顺利。
在全新安装阶段测试失败,因为应用程序上下文被初始化两次。
例如,它尝试两次创造H2表和做则将insert.sql脚本两次。
我要做的只有一次初始化数据库H2等应用程序上下文?
谢谢
我想你可以开始寻找关于Integration Testing Spring文档。
它也可以用于集成测试的事务测试(@Transactional
),其回滚在每次测试结束一个很好的做法:看Transaction Management。
ApplicationContext
:为了避免重新创建为每个测试类Context Caching的成本,因为这里解释可以使用缓存。
对于嵌入式数据库集成测试,你还可以找到文档:Testing Data Access Logic with an Embedded Database。从以前的链接的说明,符合你的使用情况:
但是,如果你想创建一个测试套件内共享的嵌入式数据库,可以考虑使用Spring TestContext框架,并通过使用Spring XML和创建在创建嵌入式数据库说明配置了嵌入式数据库在Spring的ApplicationContext一个bean嵌入式数据库编程。
我希望你能找到一些有用的参考。
在单元测试必须garantee每个测试是独立repeatible汉斯上下文。由于这不加载上下文只有一次不错的主意。为更好地执行后复位。为此,您可以在您的测试类使用@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
所以,你会强迫你的情况下重新启动下一个JUnit类启动
另一个很好的提示,我从春天启动文件发现从Embedded Database Support:
他们说 :
如果您使用的是你的测试此功能,您可能会注意到,同样的数据库是由你的整个测试套件,无论您使用的应用程序上下文的数量的重复使用。如果你想确保每个方面都有一个独立的嵌入式数据库,你应该设置spring.datasource.generate唯一名称为true。
因此,为了使每个EmbeddedDatabase
独特,您可以尝试与创建它们:
EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
...
.build();
所以,这是失败的原因是数据库(H2)是驻留在内存中,当您运行测试作为清洁部分/安装。运行第一次测试后,创建/插入脚本已经执行。这点之后的任何后续测试执行将导致在同一个脚本(或多个),并且将发生该错误的重新执行。
更新您创建脚本以DROP TABLE IF EXISTS <table name>;
。这将确保该表被删除,然后重新创建。
注:我不知道为什么你明确指定AnnotationConfigContextLoader
。我想,没有这个,亚军SpringJUnit4ClassRunner
将缓存是没有改变的背景下。我不知道具体是,如果是这样的话,虽然在这里。