Существует ли какая-либо структура, которая просто откатывает все транзакции после каждого теста, чтобы каждый тест имел свежие / одинаковые данные БД для тестирования. И таким образом после всех тестовых выполнений данные схемы БД будут такими, как есть.
Из моего другого ответа , опубликованного ранее днем, да, это возможно с помощью DbUnit. (Исходя из ваших правок, вам это не нужно; в следующем разделе моего ответа рассматривается, почему я использую DbUnit, а когда я не буду его использовать).
Следующий фрагмент кода демонстрирует, как выполняется настройка каждого теста:
@Before
public void setUp() throws Exception
{
logger.info("Performing the setup of test {}", testName.getMethodName());
IDatabaseConnection connection = null;
try
{
connection = getConnection();
IDataSet dataSet = getDataSet();
//The following line cleans up all DbUnit recognized tables and inserts and test data before every test.
DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
}
finally
{
// Closes the connection as the persistence layer gets it's connection from elsewhere
connection.close();
}
}
private IDatabaseConnection getConnection() throws Exception
{
@SuppressWarnings({ "rawtypes", "unused" })
Class driverClass = Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection jdbcConnection = DriverManager.getConnection(jdbcURL, "XXX",
"YYY");
IDatabaseConnection databaseConnection = new DatabaseConnection(jdbcConnection);
return databaseConnection;
}
private IDataSet getDataSet() throws Exception
{
ClassLoader classLoader = this.getClass().getClassLoader();
return new FlatXmlDataSetBuilder().build(classLoader.getResourceAsStream("database-test-setup.xml"));
}
Файл database-test-setup.xml
содержит данные, которые будут вставляться в базу данных для каждого теста. Использование DatabaseOperation.CLEAN_INSERT
в методе setup
гарантирует, что все таблицы, указанные в файле, будут очищены (путем удаления всех строк) с последующей вставкой указанных данных в файл тестовых данных.
Как избежать DbUnit
Я использую описанный выше подход специально для очистки последовательностей перед началом каждого теста, так как приложение использует провайдера JPA, который обновляет последовательности в отдельной транзакции. Если ваше приложение не делает ничего подобного, то вы можете позволить себе просто запустить транзакцию в вашем методе setup()
и выполнить откат после завершения проверки. Если бы мое приложение не использовало последовательности (и если бы я не хотел сбрасывать их), то моя процедура установки была бы такой простой, как:
@Before
public void setUp() throws Exception
{
logger.info("Performing the setup of test {}", testName.getMethodName());
// emf is created in the @BeforeClass annotated method
em = emf.createEntityManager();
// Starts the transaction before every test
em.getTransaction.begin();
}
@After
public void tearDown() throws Exception
{
logger.info("Performing the teardown of test {}", testName.getMethodName());
if (em != null)
{
// Rolls back the transaction after every test
em.getTransaction().rollback();
em.close();
}
}
Кроме того, я использую dbdeploy с Maven, но это в первую очередь для поддержания базы данных тестирования в актуальном состоянии с версионной моделью данных.