JUnit + Derby + Spring: падение в памяти db после каждого теста
в моих модульных тестах я autowired некоторые источники данных, которые используют URL-адреса, такие как
jdbc:derby:memory:mydb;create=true
для создания DBs в памяти.
чтобы удалить в памяти Derby db, вы должны связаться с:
jdbc:derby:memory:mydb;drop=true
Я хотел бы, чтобы это происходило после каждого теста и начиналось со свежей БД. Как я могу сделать это с помощью Spring?
6 ответов
существует агностический способ сделать это, если вы используете Spring вместе с Hibernate.
убедитесь, что контекст приложения будет создан / уничтожен до / после каждого метода тестирования:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:application-context-test.xml"})
@TestExecutionListeners({DirtiesContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class AbstractTest {
}
проинструктировать Hibernate автоматически создавать схему при запуске и удалять схему при завершении работы:
hibernate.hbm2ddl.auto = create-drop
Теперь перед каждым тестом
- создается контекст приложения и вводятся необходимые весенние бобы (весна)
- создаются структуры базы данных (hibernate)
- импорт.sql выполняется, если присутствует (hibernate)
и после каждого испытания
- контекст приложения уничтожается (весна)
- схема базы данных удалена (спящий режим).
Если вы используете транзакции, вы можете добавить TransactionalTestExecutionListener
.
Как правильно отключить базу данных Derby в памяти
дал мне подсказку к решению:
mydb.drop.url = jdbc:derby:memory:mydb;drop=true
...
<bean id="mydbDropUrl" class="java.lang.String">
<constructor-arg value="${mydb.drop.url}" />
</bean>
...
@Resource
private String mydbDropUrl;
@After
public void tearDown() {
try {
DriverManager.getConnection(mydbDropUrl);
} catch (SQLException e) {
// ignore
}
}
недостатком является использование строкового конструктора, который принимает строку (неизменяемый строковый объект вокруг неизменяемого строкового объекта). Я читал, что в Spring 3 есть аннотация @Value, которая может помочь здесь, но я использую Spring 2.5.
пожалуйста, дайте мне знать, если у вас есть лучше решение.
после весеннего теста 3 Вы можете использовать аннотации для ввода конфигураций:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
просто сделайте что-то вроде:
public class DatabaseTest implements ApplicationContextAware {
private ApplicationContext context;
private DataSource source;
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
@Before
public void before() {
source = (DataSource) dataSource.getBean("dataSource", DataSource.class);
}
@After
public void after() {
source = null;
}
}
Сделайте ваш bean иметь область прототипа (scope="prototype"
). Это позволит получить новый экземпляр источника данных перед каждым тестом.
Если вы используете весна-теста.Джар библиотеки, вы можете сделать что-то вроде этого:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.deleteFromTables(new String[]{"myTable"});
super.executeSqlScript("file:db/load_data.sql", true);
}
}
и обновленная версия на основе последнего комментария, которая отбрасывает БД и воссоздает таблицы перед каждым тестом:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.executeSqlScript("file:db/recreate_tables.sql", true);
}
}
Это то, что мы делаем в начале каждого теста.
удалить все предыдущие объекты.
создайте все таблицы, упомянутые в create_table.в SQL
-
вставить значения на созданные таблицы на основе того, что вы хотите проверить.
@Before public void initialInMemoryDatabase() throws IOException, FileNotFoundException { inMemoryDerbyDatabase.dropAllObjects(); inMemoryDerbyDatabase.executeSqlFile("/create_table_policy_version_manager.sql"); inMemoryDerbyDatabase.executeSqlFile("/insert_table_policy_version_manager.sql"); }
работает как шарм!