如何以编程方式为 Spring 中的集成测试填充测试数据?
How to populate test data programmatically for integration tests in Spring?
我正在寻找使用 spring / spring 引导在集成测试中以编程方式填充测试数据的推荐方法。我正在使用 HSQLDB(在内存中)。
可以在 spring 中执行 SQL 脚本来进行这样的集成测试:
@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
// execute code that relies on the test schema and test data
}
我不想编写 SQL 脚本,而是想在一个集成测试中以编程方式为 多个 测试方法插入数据,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookstoreApp.class)
@IntegrationTest
public class BookRepositoryTest {
@Autowired
private BookRepository bookRepository;
@Before // not working
public void setUp() throws Exception {
bookRepository.save(new Book("Donald Duck 1", "Walt Disney", "0-14-020652-3"));
bookRepository.save(new Book("Donald Duck 2", "Walt Disney", "0-14-020652-4"));
bookRepository.save(new Book("Micky Mouse", "Walt Disney", "0-14-020652-5"));
}
@Test
public void findByTitle() {
List<Book> books = bookRepository.findByTitle("Duck");
Assert.assertEquals(2, books.size());
}
@Test
public void getByIsbn() {
Book book = bookRepository.getByIsbn("0-14-020652-4");
Assert.assertEquals("0-14-020652-4", book.getIsbn());
Assert.assertEquals("Donald Duck 2", book.getTitle());
}
}
这个例子的每个测试在单独执行时运行得很好。但是当 运行 它们在一起时,第二个 (getByIsbn) 将失败。所以显然 @Before
是这里使用的错误注释,因为书籍将被插入两次。
如何强制数据库设置只执行一次?
将 @IntegrationTest
替换为 @Transactional
(在 class 级别)应该可以解决您的问题。
推理:
@IntegrationTest
启动您的整个 Spring 引导应用程序,但这对于您的场景来说似乎有点过分了。
@Transactional
将导致您的测试在测试管理的事务中执行,该事务将在测试完成后回滚; @Before
方法中执行的代码将在测试管理的事务中执行。
我正在寻找使用 spring / spring 引导在集成测试中以编程方式填充测试数据的推荐方法。我正在使用 HSQLDB(在内存中)。
可以在 spring 中执行 SQL 脚本来进行这样的集成测试:
@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
// execute code that relies on the test schema and test data
}
我不想编写 SQL 脚本,而是想在一个集成测试中以编程方式为 多个 测试方法插入数据,如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookstoreApp.class)
@IntegrationTest
public class BookRepositoryTest {
@Autowired
private BookRepository bookRepository;
@Before // not working
public void setUp() throws Exception {
bookRepository.save(new Book("Donald Duck 1", "Walt Disney", "0-14-020652-3"));
bookRepository.save(new Book("Donald Duck 2", "Walt Disney", "0-14-020652-4"));
bookRepository.save(new Book("Micky Mouse", "Walt Disney", "0-14-020652-5"));
}
@Test
public void findByTitle() {
List<Book> books = bookRepository.findByTitle("Duck");
Assert.assertEquals(2, books.size());
}
@Test
public void getByIsbn() {
Book book = bookRepository.getByIsbn("0-14-020652-4");
Assert.assertEquals("0-14-020652-4", book.getIsbn());
Assert.assertEquals("Donald Duck 2", book.getTitle());
}
}
这个例子的每个测试在单独执行时运行得很好。但是当 运行 它们在一起时,第二个 (getByIsbn) 将失败。所以显然 @Before
是这里使用的错误注释,因为书籍将被插入两次。
如何强制数据库设置只执行一次?
将 @IntegrationTest
替换为 @Transactional
(在 class 级别)应该可以解决您的问题。
推理:
@IntegrationTest
启动您的整个 Spring 引导应用程序,但这对于您的场景来说似乎有点过分了。@Transactional
将导致您的测试在测试管理的事务中执行,该事务将在测试完成后回滚;@Before
方法中执行的代码将在测试管理的事务中执行。