My next problem testing spring service layer with junit4 is: How to call script that populates database only once before all @Test methods: I want to execute this once before all @Tests:
JdbcTestUtils.executeSqlScript(jdbcTemplate(), new FileSystemResource(
"src/main/resources/sql/mysql/javahelp-insert.sql"), false);
I tried to use @PostConstruct on my GenericServiceTest class(extended by test classes). It turned out that @PostConstruct is called every time before every @Test method. Interesting is that even methods annotated @Autowired of GenericServiceTest are called before every @Test method.
I don't want to populate database before every test class but only once at spring-test startup.
How to execute above method only once before all @Test methods with spring testing framework and junit4?
Thank you!
Use Springs Embedded Database Support
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:myScript.sql"/>
<jdbc:script location="classpath:otherScript.sql"/>
</jdbc:embedded-database>
or Springs Initialize Database Support
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:myScript.sql"/>
<jdbc:script location="classpath:otherScript.sql"/>
</jdbc:initialize-database>
Building on Alfredos answer, this is a way to inject database information without calling the embedded database's default script. For instance, this may be useful when you want to automagically build the DDL for you - at least in tests.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/applicationContext.xml"})
public class TestClass {
@Autowired
private ApplicationContext ctx;
private JdbcTemplate template;
@Autowired
public void setDataSource(DataSource dataSource) {
template = new JdbcTemplate(dataSource);
}
private static boolean isInitialized = false;
@Before
public void runOnce() {
if (isInitialized) return;
System.out.println("Initializing database");
String script = "classpath:script.sql";
Resource resource = ctx.getResource(script);
JdbcTestUtils.executeSqlScript(template, resource, true);
isInitialized = true;
}
}
This way, the runOnce()
method is called once and only once for the test run. If you make isInitialized
an instance field (non-static), the method will be called before every test. This way you can drop/repopulate the tables, if necessary, before every test run.
Note that this is still a rather quick-and-dirty solution and the sensible way to handle the database is in accordance with Ralph's answer.
in case you are spring boot, u can mention multiple scripts to launch before tests via
spring.datasource.data=classpath:accounts.sql, classpath:books.sql, classpath:reviews.sql
来源:https://stackoverflow.com/questions/17505952/how-to-populate-database-only-once-before-test-methods-in-spring-test