JUnit + Derby + Spring: падение базы данных в памяти после каждого теста - PullRequest
6 голосов
/ 18 января 2011

В своих модульных тестах я автоматически подключал некоторые источники данных, которые используют URL-адреса, такие как

jdbc:derby:memory:mydb;create=true

, для создания БД в памяти.

Чтобы сбросить дерби в памяти в памяти, вы должнысоединиться с:

jdbc:derby:memory:mydb;drop=true

Я хотел бы, чтобы это происходило после каждого теста и начиналось с новой базы данных.Как я могу сделать это с помощью Spring?

Ответы [ 6 ]

5 голосов
/ 11 мая 2012

Существует независимый от базы данных способ сделать это, если вы используете 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

Теперь перед каждым тестом

  • создается контекст приложения и вводятся необходимые пружинные бины (spring)
  • структуры базы данных созданы (в спящем режиме)
  • import.sql выполняется, если присутствует (в спящем режиме)

и после каждого теста

  • контекст приложения уничтожен (весна)
  • схема базы данных удалена (спящий режим).

Если вы используете транзакции, вы можете добавить TransactionalTestExecutionListener.

4 голосов
/ 18 января 2011

Как правильно завершить работу базы данных 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
    }
}

Недостатком является использование конструктора Stringкоторый принимает String (неизменный объект String вокруг неизменного объекта String).Я читал, что в Spring 3 есть аннотация @Value, которая может помочь, но я использую Spring 2.5.

Пожалуйста, дайте мне знать, если у вас есть более подходящее решение.

2 голосов
/ 16 декабря 2011

После весеннего теста 3 вы можете использовать аннотации для ввода конфигурации:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
1 голос
/ 18 января 2011

Просто сделайте что-то вроде:

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;
    }
}

Сделайте так, чтобы у вашего компонента был прототип (scope="prototype").Это будет получать новый экземпляр источника данных перед каждым тестом.

1 голос
/ 18 января 2011

Если вы используете библиотеку spring-test.jar , вы можете сделать что-то вроде этого:

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);
        }
}
0 голосов
/ 06 мая 2016

Это то, что мы делаем в начале каждого теста.

  1. Бросить все предыдущие объекты.

  2. Создать все таблицы, упомянутые в create_table.sql

  3. Вставьте значения в созданные таблицы в зависимости от того, что вы хотите проверить.

      @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");
    
      }
    

Работает как шарм!

...