I’m looking for a way to run some TestNG tests against multiple DataSources. I’ve seen the DataProvider options for TestNG, but they don’t quite do what I want. I want to run some really simple tests against my MyBatis mappers, mainly to make sure I don’t have any simple syntax errors, typos, etc. Right now, I have a base test class like this:
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();
}
}
Then I create a test for each mapper:
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));
}
}
What I’d like to do is run each test class twice (or more), using a different SqlSessionManager each time. I can use TestNG’s DataProvider to run each test with multiple SqlSessionManagers, but then I have to start & rollback the session inside each test rather than in @BeforeMethod.
Is there an easy way to accomplish what I want?
I think I’ve got this figured out after stumbling across this post. The trick is to use a combination of
@Factoryand@DataProvider. First I created an abstract base class that manages the provider and the transactions.Then I use the
@Factoryannotation on the constructor of extending classes. This has the effect of creating one instance of the test class perSqlSessionManagerfrom my@DataProvider.When I run my tests, two instances of the
SequenceMapperTestget created, one for eachSqlSessionManagerthat I set up in the@DataProvider. So far, it seems to be working, but my IDE (IntelliJ IDEA) has a bit of trouble splitting the logging output from each individual test.