figuration
@ComponentScan(basePackageClasses = FooRepository.class)
public class Spring_2_IT_Configuration {
@Bean
public DataSource dataSource() {
EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("classpath:me/chanjar/domain/foo-ddl.sql")
.build();
return db;
}
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
这里和例子1的区别在于,我们提供了一个PlatformTransactionManager Bean,这是因为在下面的测试代码里的AbstractTransactionalTestNGSpringContextTests需要它。
Spring_2_IT.java:
@ContextConfiguration(classes = Spring_2_IT_Configuration.class)
public class Spring_2_IT extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
private FooRepository fooRepository;
@Test
public void testSave() {
Foo foo = new Foo();
foo.setName("Bob");
fooRepository.save(foo);
assertEquals(countRowsInTable("FOO"), 1);
countRowsInTableWhere("FOO", "name = 'Bob'");
}
@Test(dependsOnMethods = "testSave")
public void testDelete() {
assertEquals(countRowsInTable("FOO"), 0);
Foo foo = new Foo();
foo.setName("Bob");
fooRepository.save(foo);
fooRepository.delete(foo.getName());
assertEquals(countRowsInTable("FOO"), 0);
}
}
在这里我们使用countRowsInTable(“FOO”)来验证数据库结果,这个方法是AbstractTransactionalTestNGSpringContextTests对JdbcTestUtils的代理。
而且要注意的是,每个测试方法在执行完毕后,会自动rollback,所以在testDelete的第一行里,我们assertEquals(countRowsInTable(“FOO”), 0),这一点和例子1里是不同的。
更多关于Spring Testing Framework与Transaction相关的信息,可以见Spring官方文档 Transaction management。
例子3:使用Spring Boot
Boot_1_IT.java:
@SpringBootTest
@SpringBootApplication(scanBasePackageClasses = FooRepository.class)
public class Boot_1_IT extends AbstractTransactionalTestNGSpringContextTests {
@Autowired
private FooRepository fooRepository;
@Test
public void testSave() {
Foo foo = new Foo();
foo.setName("Bob");
fooRepository.save(foo);
assertEquals(countRowsInTable("FOO"), 1);
countRowsInTableWhere("FOO", "name = 'Bob'");
}
@Test(dependsOnMethods = "testSave")
public void testDelete() {
assertEquals(countRowsInTable("FOO"), 0);
Foo foo = new Foo();
foo.setName("Bob");
fooRepository.save(foo);
fooRepository.delete(foo.getName());
assertEquals(countRowsInTable("FOO"), 0);
}
@AfterTest
public void cleanDb() {
flyway.clean();
}
}
因为使用了Spring Boot来做集成测试,得益于其AutoConfiguration机制,不需要自己构建DataSource 、JdbcTemplate和PlatformTransactionManager的Bean。
并且因为我们已经将flyway-core添加到了maven依赖中,Spring Boot会利用flyway来帮助我们初始化数据库,我们需要做的仅仅是将sql文件放到classpath的db/migration目录下:
V1.0.0__foo-ddl.sql:
CREATE TABLE FOO (
name VARCHAR2(100)
);
而且在测试最后,我们利用flyway清空了数据库:
@AfterTest
public void cleanDb() {
flyway.clean();
}
使用flyway有很多好处:
- 每个sql文件名都规