Тест управления весенними транзакциями - PullRequest
2 голосов
/ 09 июня 2009

Я хочу проверить свой класс Dao, используя SpringContextTests.
В моем классе методов я расширил AbstractTransactionalJUnit4SpringContextTests, чтобы мой тестовый класс интегрировался с JUnit4. Я также настроил конфигурации и произвел очистку инициализации и базы данных в @Before и tearDown в @After. Мой тестовый класс работает отлично.

Моя проблема заключалась в том, что когда я запускаю свой тестовый класс и база данных заполнена данными, исходные данные не были откатаны, а моя база данных очищена. В методе @Before я очищаю базу данных и заполняю данные, думая, что смогу откатить ее, но это не так.

Может кто-нибудь на сайте привести пример, который работает и откатывает информацию в базе данных.

ДОБАВЛЯЕТ:
Все манипуляции с базой данных в моих тестовых методах откатываются. Но выполнение super.deleteFromTables("person") в методе @Before не откатило все предыдущие данные из базы данных.

Spring откатывает все операции CRUD, но база данных очищается до того, как транзакция не откатывается.

Ответы [ 8 ]

2 голосов
/ 11 июня 2009

Спасибо всем, кто ответил на мой вопрос. Из этих ответов я многому научился, но это не решило мою проблему.
Я знал, что мои тестовые данные выполняют управление транзакциями и выполняют свою работу должным образом.
Ошибка с моей стороны.

Я забыл урок о командах базы данных: когда вы выполняете оператор DDL после оператора DML, он автоматически фиксирует транзакцию. Я выполнил DDL после DML, удалив все записи, а затем ALTER AUTO_INCREMENT таблицы, в которой это приведет к автоматической фиксации и навсегда удалит все записи таблицы.

ИСПРАВЛЕНИЕ, СЦЕНАРИЙ РЕШЕН, МОЯ ПРОБЛЕМА.

1 голос
/ 10 июня 2009

Я не уверен, что не так с вашим классом. Вот выдержка из класса, который делает то, что вы хотите с dbunit и spring 2.5:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
  "testContext.xml"})
@TransactionConfiguration
@Transactional
public class SampleDAOTest {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private SampleDAO sampleDAO;

    @Before 
    public void onSetUpInTransaction() throws Exception {
        //Populate Test data
        IDatabaseConnection dbUnitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource), "DATASOURCE");
            //read in from a dbunit excel file of test data
        IDataSet dataSet = new XlsDataSet(new File("src/test/resources/TestData.xls"));
        DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
    }


    @Test
    public void testGetIntermediaryOrganisation() {

        // Test getting a user
        User object = sampleDAO.getUser(99L);
        assertTrue(object.getValue);


    }
}

Одним из преимуществ этого метода является то, что вам не нужно расширять какие-либо классы. Таким образом, у вас все еще может быть своя собственная иерархия для тестов.

Если вы действительно хотите придерживаться текущего метода, а не использовать аннотацию @before, я думаю, вам нужно переопределить приведенный ниже метод и поместить туда свой установочный код.

@Override
public void onSetUpInTransaction() throws Exception {...}

Надеюсь, это поможет

1 голос
/ 10 июня 2009

Возможные причины:

  • вы используете базу данных / ядро ​​базы данных, которое не имеет правильных транзакций;
  • вы используете несколько менеджеров транзакций и / или источников данных, а нужный не выбран;
  • вы выполняете свои собственные, отдельные транзакции в тестовом классе

Как пример, вот один (верхняя часть моей головы, не скомпилированный)

public class DBTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private SomeDAO _aBeanDefinedInMyContextFile;

    @Test
    public void insert_works() {
        assert _aBeanDefinedInMyContextFile.findAll() == 0;
        _aBeanDefinedInMyContextFile.save(new Bean());
        assert _aBeanDefinedInMyContextFile.findAll() == 1;
    }


}

Ключевые моменты:

  • SomeDAO - это интерфейс, который соответствует компоненту, объявленному в моем контексте;
  • бин не имеет каких-либо транзакционных настроек (консультативных / программных), он полагается на то, что вызывающая сторона является транзакционной - либо работающая служба, либо тест в нашей ситуации;
  • тест не включает никакого кода управления транзакциями, так как все это делается в платформе.
0 голосов
/ 15 июля 2009

Вы делаете super.deleteFromTables в своем методе @Before, который находится в пределах tx. Так что, если откат TX откатов не откатится также?

0 голосов
/ 10 июня 2009

Насколько я могу судить, взглянув на Javadocs и исходный код для AbstractJUnit4SpringContextTests и TransactionalTestExecutionListener, вы должны аннотировать ваши тестовые методы, которые вы хотите транзакции, с помощью @ Transactional.

Существуют также аннотации @BeforeTransaction и @AfterTransaction, где вы можете лучше контролировать то, что выполняется в транзакции.

Я предлагаю вам создать методы, аннотированные всеми этими аннотациями, включая @Before, а затем запустить тест с контрольными точками для этих методов. Таким образом, вы можете посмотреть на стек и понять, начала ли Spring для вас транзакцию или нет. Если вы видите что-то вроде «TransactionInterceptor» в стеке или что-то еще с «Transaction» в названии, то, скорее всего, вы находитесь в транзакции.

0 голосов
/ 09 июня 2009

Хотя я согласен с тем, что парень предложил отклонить БД для тестирования, нет никаких причин, по которым использование заполненной БД не должно работать, оба метода @Before и @After выполняются в контексте транзакции, поэтому изменения должны быть отменены.

с-плюс:

  • Настройка данных делает что-то не транзакционное (например, операторы DDL)
  • Что-то в вашем тесте фактически совершает транзакцию

Можете ли вы опубликовать метод @Before, мне просто интересно, очищаете ли вы таблицы или просто удаляете и воссоздаете их?

0 голосов
/ 09 июня 2009

Согласитесь с Confusion-- вы должны запускать свои тесты по их собственной схеме базы данных.

С этим вы можете установить свои свойства гибернации в 'create-drop':

С create-drop, схема базы данных будет отброшен, когда SessionFactory закрыт явно.

См .: Дополнительные свойства Hibernate Config

Пример фрагмента:

<bean id="sessionBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
         ...etc
0 голосов
/ 09 июня 2009

В дополнение к вашему вопросу, я предлагаю вам использовать отдельный экземпляр базы данных для выполнения ваших тестов. Таким образом, вы можете безопасно стереть его и сделать так, чтобы ваши тесты инициализировали его по мере необходимости.

Насколько мне известно, классы поддержки Spring для тестирования базы данных только откат того, что происходит в тестах, а не то, что происходит при настройке и разборке тестов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...