I am looking for the recommended approach for populating test data programmatically in integration tests using spring / spring boot. I am using HSQLDB (inmemory).
There is the possibility to execute SQL scripts in spring for integration tests like this:
@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
// execute code that relies on the test schema and test data
}
Instead of writing SQL scripts I would like to insert data for multiple test methods in one integration test programmatically like this:
@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());
}
}
Each Test of this example runs just fine when being executed separately. But the second one (getByIsbn) will fail, when running them together. So obviously @Before
is the wrong annotation to use here, since the books will be inserted twice.
How can I enforce the database setup being executed only once?
@BeforeClass
is not working since spring context won't be up at that time, but@After
would be possible. Not the nicest approach I think, since you need to keep track of everything you inserted. – fischermattespring-test
and Spring Boot are you using? – Sam Brannen