我使用Junit进行spring-test,我希望通过这个注释进行经典的事务测试:
@Injectdata("classpath:src/test/mydata.sql")
@Test
public void myTest throws Exception {
// ...
}
此数据将在同一事务中使用jdbcspring模板注入。这些数据将可用 只有这个测试。
实际上,我以这种方式注入数据:
@Test
public void myTest throws Exception {
jdbcTemplate.update("my sql query);
}
我知道Unitils框架使用数据集dbunit文件做同样的事情。
答案 0 :(得分:3)
我自己创建了一个解决方案。
首先创建Spring测试使用的监听器:
public class InjectDataTestExecutionListener extends DependencyInjectionTestExecutionListener {
private static JdbcTemplate jdbcTemplate;
private static DataSource datasource ;
private static String ENCODING="UTF-8";
@Override
/**
* Execute un éventuel script SQL indiqué via l'annotation {@link SqlFileLocation}
* avant l'execution d'un test.
*/
public void beforeTestMethod(TestContext testContext) throws Exception {
super.beforeTestClass(testContext);
Method MyMethdo = testContext.getTestMethod();
SqlFileLocation dsLocation = MyMethdo.getAnnotation(SqlFileLocation.class);
if (dsLocation!=null){
executeSqlScript(testContext,dsLocation.value());
}
}
/**
* Execute un script sur un chemin d'accès au fichier.
* @param testContext le context du test
* @param sqlResourcePath le chemin du fichier Sql
* @throws DataAccessException en cas d'erreur d'accès au fichier
*/
private void executeSqlScript(TestContext testContext, String sqlResourcePath) throws DataAccessException {
JdbcTemplate jdbcTemplate = getJdbCTemplate(getDatasource(testContext));
Resource resource = testContext.getApplicationContext().getResource(sqlResourcePath);
executeSqlScript(jdbcTemplate, new EncodedResource(resource,ENCODING));
}
private DataSource getDatasource(TestContext testContext) {
if (datasource==null){
datasource = testContext.getApplicationContext().getBean(DataSource.class);
}
return datasource;
}
private JdbcTemplate getJdbCTemplate(DataSource datasource) {
if (jdbcTemplate==null){
jdbcTemplate = new JdbcTemplate(datasource);
}
return jdbcTemplate;
}
/**
* Execute une resource via un jdbcTemplate donné.
* @throws DataAccessException enc as de pb d'acces au fichier.
*/
private static void executeSqlScript(JdbcTemplate simpleJdbcTemplate,
EncodedResource resource) throws DataAccessException {
List<String> statements = new LinkedList<String>();
try {
LineNumberReader lnr = new LineNumberReader(resource.getReader());
String script = JdbcTestUtils.readScript(lnr);
char delimiter = ';';
if (!JdbcTestUtils.containsSqlScriptDelimiters(script, delimiter)) {
delimiter = '\n';
}
JdbcTestUtils.splitSqlScript(script, delimiter, statements);
for (String statement : statements) {
try {
simpleJdbcTemplate.update(statement);
}
catch (DataAccessException ex) {
throw ex;
}
}
}
catch (IOException ex) {
throw new DataAccessResourceFailureException("Impossible d'ouvrir le script depuis " + resource, ex);
}
}
}
比你的班级测试添加:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={/* ... */})
@Transactionnal
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class,TransactionalTestExecutionListener.class
,InjectDataTestExecutionListener.class
})
TRICK 是添加通常由Spring自动添加的所有侦听器,如果您不添加侦听器。避免这会导致奇怪的错误。
这没有记录,但是我发现如果没有带有transactionnal spring测试的监听器,Spring会自动添加这3个监听器(感谢调试模式!)
最后,你给我们这个很酷的注释:
@SqlFileLocation("classpath:sql/myfil.sql")
@Test
public void testGetAll() throws Exception {/*...*/}
您甚至可以使用相对路径或绝对路径。
自然插入将像其他插入一样自动回滚。
答案 1 :(得分:0)
也许@Sql注释可以做得更好。