RESOLVED - BATCH-143: uniform tests for IO sources
abstract CommonItemStreamItemReaderTests added + subclasses that setup different reader implementations
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package org.springframework.batch.item;
|
||||
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Common tests for {@link ItemReader} implementations. Expected input is five
|
||||
* {@link Foo} objects with values 1 to 5.
|
||||
*/
|
||||
public abstract class CommonItemReaderTests extends TestCase {
|
||||
|
||||
protected ItemReader tested;
|
||||
|
||||
/**
|
||||
* @return configured ItemReader ready for use.
|
||||
*/
|
||||
protected abstract ItemReader getItemReader() throws Exception;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
tested = getItemReader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular scenario - read the input and eventually return null.
|
||||
*/
|
||||
public void testRead() throws Exception {
|
||||
|
||||
Foo foo1 = (Foo) tested.read();
|
||||
assertEquals(1, foo1.getValue());
|
||||
|
||||
Foo foo2 = (Foo) tested.read();
|
||||
assertEquals(2, foo2.getValue());
|
||||
|
||||
Foo foo3 = (Foo) tested.read();
|
||||
assertEquals(3, foo3.getValue());
|
||||
|
||||
Foo foo4 = (Foo) tested.read();
|
||||
assertEquals(4, foo4.getValue());
|
||||
|
||||
Foo foo5 = (Foo) tested.read();
|
||||
assertEquals(5, foo5.getValue());
|
||||
|
||||
assertNull(tested.read());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback scenario - reader resets to last marked point.
|
||||
*/
|
||||
public void testReset() throws Exception {
|
||||
Foo foo1 = (Foo) tested.read();
|
||||
|
||||
tested.mark();
|
||||
|
||||
Foo foo2 = (Foo) tested.read();
|
||||
Assert.state(!foo2.equals(foo1));
|
||||
|
||||
Foo foo3 = (Foo) tested.read();
|
||||
Assert.state(!foo2.equals(foo3));
|
||||
|
||||
tested.reset();
|
||||
|
||||
assertEquals(foo2, tested.read());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.batch.item;
|
||||
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
|
||||
/**
|
||||
* Common tests for readers implementing both {@link ItemReader} and
|
||||
* {@link ItemStream}. Expected input is five {@link Foo} objects with values 1
|
||||
* to 5.
|
||||
*/
|
||||
public abstract class CommonItemStreamItemReaderTests extends CommonItemReaderTests {
|
||||
|
||||
protected ExecutionContext executionContext = new ExecutionContext();
|
||||
|
||||
/**
|
||||
* Cast the reader to ItemStream.
|
||||
*/
|
||||
protected ItemStream testedAsStream() {
|
||||
return (ItemStream) tested;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
testedAsStream().open(executionContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
testedAsStream().close(executionContext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Restart scenario - read items, update execution context, create new
|
||||
* reader and restore from restart data - the new input source should
|
||||
* continue where the old one finished.
|
||||
*/
|
||||
public void testRestart() throws Exception {
|
||||
|
||||
Foo foo1 = (Foo) tested.read();
|
||||
assertEquals(1, foo1.getValue());
|
||||
|
||||
Foo foo2 = (Foo) tested.read();
|
||||
assertEquals(2, foo2.getValue());
|
||||
|
||||
testedAsStream().update(executionContext);
|
||||
|
||||
// create new input source
|
||||
tested = getItemReader();
|
||||
|
||||
testedAsStream().open(executionContext);
|
||||
|
||||
Foo fooAfterRestart = (Foo) tested.read();
|
||||
assertEquals(3, fooAfterRestart.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,9 +20,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -88,10 +86,8 @@ public class BatchSqlUpdateItemWriterTests extends TestCase {
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
protected void tearDown() throws Exception {
|
||||
Map map = TransactionSynchronizationManager.getResourceMap();
|
||||
for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
|
||||
String key = (String) iterator.next();
|
||||
TransactionSynchronizationManager.unbindResource(key);
|
||||
if (TransactionSynchronizationManager.hasResource(BatchSqlUpdateItemWriter.ITEMS_PROCESSED)) {
|
||||
TransactionSynchronizationManager.unbindResource(BatchSqlUpdateItemWriter.ITEMS_PROCESSED);
|
||||
}
|
||||
RepeatSynchronizationManager.clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.batch.item.CommonItemStreamItemReaderTests;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public abstract class CommonDatabaseItemStreamItemReaderTests extends CommonItemStreamItemReaderTests {
|
||||
|
||||
private ClassPathXmlApplicationContext ctx;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
ctx = new ClassPathXmlApplicationContext("foo-data-source-context.xml", JdbcCursorItemReaderCommonTests.class);
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
protected DataSource getDataSource() {
|
||||
return (DataSource) ctx.getBean("dataSource");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
||||
|
||||
public class HibernateCursorItemReaderCommonTests extends CommonDatabaseItemStreamItemReaderTests {
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
|
||||
factoryBean.setDataSource(getDataSource());
|
||||
factoryBean.setMappingLocations(new Resource[] { new ClassPathResource("Foo.hbm.xml", getClass()) });
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
SessionFactory sessionFactory = (SessionFactory) factoryBean.getObject();
|
||||
|
||||
String hsqlQuery = "from Foo";
|
||||
|
||||
HibernateCursorItemReader reader = new HibernateCursorItemReader();
|
||||
reader.setQueryString(hsqlQuery);
|
||||
reader.setSessionFactory(sessionFactory);
|
||||
reader.setUseStatelessSession(true);
|
||||
reader.afterPropertiesSet();
|
||||
reader.setSaveState(true);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.database.support.IbatisKeyCollector;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
|
||||
public class IbatisItemReaderCommonTests extends CommonDatabaseItemStreamItemReaderTests {
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
factory.setConfigLocation(new ClassPathResource("ibatis-config.xml", getClass()));
|
||||
factory.setDataSource(getDataSource());
|
||||
factory.afterPropertiesSet();
|
||||
SqlMapClient sqlMapClient = (SqlMapClient) factory.getObject();
|
||||
|
||||
IbatisDrivingQueryItemReader reader = new IbatisDrivingQueryItemReader();
|
||||
IbatisKeyCollector keyGenerator = new IbatisKeyCollector();
|
||||
keyGenerator.setDrivingQueryId("getAllFooIds");
|
||||
reader.setDetailsQueryId("getFooById");
|
||||
keyGenerator.setRestartQueryId("getAllFooIdsRestart");
|
||||
keyGenerator.setSqlMapClient(sqlMapClient);
|
||||
reader.setSqlMapClient(sqlMapClient);
|
||||
reader.setKeyCollector(keyGenerator);
|
||||
reader.setSaveState(true);
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
|
||||
public class JdbcCursorItemReaderCommonTests extends CommonDatabaseItemStreamItemReaderTests {
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
|
||||
JdbcCursorItemReader result = new JdbcCursorItemReader();
|
||||
result.setDataSource(getDataSource());
|
||||
result.setSql("select ID, NAME, VALUE from T_FOOS");
|
||||
result.setIgnoreWarnings(true);
|
||||
result.setVerifyCursorPosition(true);
|
||||
|
||||
result.setMapper(new FooRowMapper());
|
||||
result.setFetchSize(10);
|
||||
result.setMaxRows(100);
|
||||
result.setQueryTimeout(1000);
|
||||
result.setSaveState(true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.database.support.SingleColumnJdbcKeyCollector;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class SingleColumnJdbcDrivingQueryItemReaderCommonTests extends CommonDatabaseItemStreamItemReaderTests {
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource());
|
||||
SingleColumnJdbcKeyCollector keyStrategy = new SingleColumnJdbcKeyCollector(jdbcTemplate,
|
||||
"SELECT ID from T_FOOS order by ID");
|
||||
keyStrategy.setRestartSql("SELECT ID from T_FOOS where ID > ? order by ID");
|
||||
DrivingQueryItemReader reader = new DrivingQueryItemReader();
|
||||
reader.setKeyCollector(keyStrategy);
|
||||
reader.setSaveState(true);
|
||||
return new FooItemReader(reader, jdbcTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import org.springframework.batch.item.CommonItemStreamItemReaderTests;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.file.mapping.FieldSet;
|
||||
import org.springframework.batch.item.file.mapping.FieldSetMapper;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
public class FlatFileItemReaderCommonTests extends CommonItemStreamItemReaderTests {
|
||||
|
||||
private final String FOOS = "1 \n 2 \n 3 \n 4 \n 5 \n";
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
FlatFileItemReader tested = new FlatFileItemReader();
|
||||
Resource resource = new ByteArrayResource(FOOS.getBytes());
|
||||
tested.setResource(resource);
|
||||
tested.setFieldSetMapper(new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
Foo foo = new Foo();
|
||||
foo.setValue(fs.readInt(0));
|
||||
return foo;
|
||||
}
|
||||
});
|
||||
|
||||
tested.setSaveState(true);
|
||||
tested.afterPropertiesSet();
|
||||
return tested;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.springframework.batch.item.xml;
|
||||
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.Attribute;
|
||||
import javax.xml.stream.events.StartElement;
|
||||
|
||||
import org.springframework.batch.item.CommonItemStreamItemReaderTests;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.sample.Foo;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
|
||||
public class StaxEventItemReaderCommonTests extends CommonItemStreamItemReaderTests {
|
||||
|
||||
private final String FOOS = "<foos> <foo value=\"1\"/> <foo value=\"2\"/> <foo value=\"3\"/> <foo value=\"4\"/> <foo value=\"5\"/> </foos>";
|
||||
|
||||
protected ItemReader getItemReader() throws Exception {
|
||||
StaxEventItemReader reader = new StaxEventItemReader();
|
||||
reader.setResource(new ByteArrayResource(FOOS.getBytes()));
|
||||
reader.setFragmentRootElementName("foo");
|
||||
reader.setFragmentDeserializer(new EventReaderDeserializer() {
|
||||
public Object deserializeFragment(XMLEventReader eventReader) {
|
||||
Attribute attr;
|
||||
try {
|
||||
assertTrue(eventReader.nextEvent().isStartDocument());
|
||||
StartElement event = eventReader.nextEvent().asStartElement();
|
||||
attr = (Attribute) event.getAttributes().next();
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Foo foo = new Foo();
|
||||
foo.setValue(Integer.parseInt(attr.getValue()));
|
||||
return foo;
|
||||
}
|
||||
});
|
||||
|
||||
reader.setSaveState(true);
|
||||
reader.afterPropertiesSet();
|
||||
return reader;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user