我正在寻找对多个DataSource
运行一些TestNG测试的方法。我已经看到了TestNG的DataProvider
选项,但是它们并没有完全满足我的要求。我想对我的MyBatis映射器运行一些非常简单的测试,主要是确保我没有任何简单的语法错误,错别字等。现在,我有一个像这样的基本测试类:
public class MapperTestBaseH2 {
protected SqlSessionManager sessionManager;
@BeforeClass
public void beforeClass() throws SQLException, LiquibaseUpdateException {
JdbcDataSource h2DataSource = new JdbcDataSource();
h2DataSource.setURL("jdbc:h2:mem:test-db;DB_CLOSE_DELAY=-1");
sessionManager = MyBatisUtils.createSqlSessionManager(h2DataSource);
LiquibaseUpdater.update(h2DataSource.getConnection(), LiquibaseUpdater.DEFAULT_CONTEXTS);
}
@BeforeMethod
public void beforeMethod() {
sessionManager.startManagedSession();
}
@AfterMethod
public void afterMethod() {
sessionManager.rollback();
}
}
然后,我为每个映射器创建一个测试:
public class SequenceMapperTest extends MapperTestBaseH2 {
private SequenceMapper sequenceMapper;
@BeforeClass
@Override
public void beforeClass() throws SQLException, LiquibaseUpdateException {
super.beforeClass();
sequenceMapper = super.sessionManager.getMapper(SequenceMapper.class);
}
@Test
public void selectBidSequenceTest() {
sequenceMapper.selectSequence(Sequences.BID_SEQ);
}
@Test
public void updateBidSequenceTest() {
sequenceMapper.updateSequence(sequenceMapper.selectSequence(Sequences.BID_SEQ));
}
}
我想做的是每个测试类运行两次(或多次),每次使用不同的
SqlSessionManager
。我可以使用TestNG的DataProvider
来运行具有多个SqlSessionManager
的每个测试,但是随后我必须在每个测试中而不是在@BeforeMethod
中启动和回滚会话。有没有简单的方法可以完成我想要的?
最佳答案
我想在绊倒this post.之后我已经弄清楚了。诀窍是使用@Factory
和@DataProvider
的组合。首先,我创建了一个抽象基类,用于管理提供程序和事务。
public abstract class MyBatisTestBase {
public abstract SqlSessionManager getSessionManager();
@BeforeMethod
public void beforeMethod() {
getSessionManager().startManagedSession();
}
@AfterMethod
public void afterMethod() {
getSessionManager().rollback();
}
@DataProvider(name = "sql-session-manager-provider")
public static Object[][] sqlSessionManagerProvider() throws SQLException, LiquibaseUpdateException {
return new Object[][] {
{createDerbySessionManager()},
{createH2SessionManager()}
};
}
private static SqlSessionManager createDerbySessionManager() throws SQLException, LiquibaseUpdateException {
EmbeddedDataSource40 dataSource = new EmbeddedDataSource40();
dataSource.setDatabaseName("memory:test-db");
dataSource.setCreateDatabase("create");
LiquibaseUtils.update(dataSource.getConnection(), LiquibaseUtils.DEFAULT_CONTEXTS);
return MyBatisUtils.createSqlSessionManager(dataSource);
}
private static SqlSessionManager createH2SessionManager() throws SQLException, LiquibaseUpdateException {
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:mem:test-db;DB_CLOSE_DELAY=-1");
LiquibaseUtils.update(dataSource.getConnection(), LiquibaseUtils.DEFAULT_CONTEXTS);
return MyBatisUtils.createSqlSessionManager(dataSource);
}
}
然后,在扩展类的构造函数上使用
@Factory
批注。这具有从我的SqlSessionManager
为每个@DataProvider
创建一个测试类实例的效果。public class SequenceMapperTest extends MyBatisTestBase {
private final SqlSessionManager sessionManager;
private final SequenceMapper sequenceMapper;
@Factory(dataProvider = "sql-session-manager-provider")
public SequenceMapperTest(SqlSessionManager sessionManager) {
this.sessionManager = sessionManager;
this.sequenceMapper = sessionManager.getMapper(SequenceMapper.class);
}
@Test
public void selectBidSequenceTest() {
sequenceMapper.selectSequence(Sequences.BID_SEQ);
}
@Test
public void updateBidSequenceTest() {
sequenceMapper.updateSequence(sequenceMapper.selectSequence(Sequences.BID_SEQ));
}
@Override
public SqlSessionManager getSessionManager() {
return this.sessionManager;
}
}
运行测试时,将创建两个
SequenceMapperTest
实例,对于在SqlSessionManager
中设置的每个@DataProvider
一个实例。到目前为止,它似乎正在运行,但是我的IDE(IntelliJ IDEA)在拆分每个测试的日志输出时遇到了一些麻烦。关于java - 有没有一种方法可以针对多个接口(interface)实现(数据源)运行TestNG测试?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9656451/