在初始化数据库和导入数据一文中,我们探索了在Spring Boot项目中如何创建数据库的表结构,以及如何往数据库中填充初始数据。在程序开发过程中常常会在环境配置上浪费很多时间,例如在一个存在数据库组件的应用程序中,测试用例运行之前必须保证数据库中的表结构正确,并且已经填入初始数据。对于良好的测试用例,还需要保证数据库在执行用例前后状态不改变。
在之前应用的基础上,schema.sql文件中包含创建数据库表结构的SQL语句、data.sql文件中包含填充初始数据的SQL语句。这篇文章将//todo
INSERT INTO author(first_name, last_name) VALUES ("Greg", "Turnquist");
INSERT INTO book(isbn, title, author, publisher) VALUES ('9781-78439-302-1', 'Learning Spring Boot', 2, 1)
public class BookPubApplicationTests {
...
@Autowired
private DataSource ds;
private static boolean loadDataFixtures = true;
private MockMvc mockMvc;
private RestTemplate restTemplate = new TestRestTemplate();
@Before
public void setupMockMvc() {
...
}
@Before
public void loadDataFixtures() {
if (loadDataFixtures) {
ResourceDatabasePopulator populator = new
ResourceDatabasePopulator(context.getResource("classpath:/test-data.sql"));
DatabasePopulatorUtils.execute(populator, ds);
loadDataFixtures = false;
}
}
@Test
public void contextLoads() {
assertEquals(2, bookRepository.count());
}
@Test public void webappBookIsbnApi() {
...
}
@Test public void webappPublisherApi() throws Exception {
...
}
}
INSERT INTO author (id, first_name, last_name) VALUES (3, "William", "Shakespeare");
INSERT INTO publisher (id, name) VALUES (2, "Classical Books");
INSERT INTO book(isbn, title, author, publisher) VALUES ('978-1-23456-789-1', "Romeo and Juliet", 3, 2);
@Test
public void contextLoads() {
assertEquals(3, bookRepository.count());
}
spring.datasource.url=\ jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.hibernate.ddl-auto=none
我们通过Spring的ResourceDatabasePopulator和DatabasePopulatorUtils类加载test-data.sql文件,在test-data.sql文件中的数据仅仅对当前所在的*Test.java文件有效。Spring Boot自身去处理schema.sql和data.sql文件时也是依靠这两个类,这里我们不过是显式指定了我们希望执行的脚本文件。