Тестовая интеграция Spring не откатывается - PullRequest
3 голосов
/ 09 мая 2011

При записи интеграционного теста для приложения на основе Spring возникла проблема с откатом транзакции - данные вставлены, но после отката транзакции данные все еще находятся в таблице базы данных ... Spring 3.0.5, JUnit 4.8.2

Код проверки интеграции

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext.xml" })
@TransactionConfiguration(transactionManager="txManager",defaultRollback=true)
@Transactional
public class GenerateCodeStrategyTest {

  @Autowired
  @Qualifier(value = "generateCodeStrategy")
  private Strategy generateCodeStrategy;

  @Test
  @Transactional
  public void genCodeIntegrationTestCommunicationFailure() {
  //generate some parameters
  SMPPSession mockedSession = mock(SMPPSession.class);
  generateCodeStrategy.setSession(mockedSession);
  generateCodeStrategy.sendRequest(params);
  final SubscribeInfo subscribeInfo = subscribeDao.getUserByPhone(phone);
  assertNotNull(subscribeInfo);
  assertEquals(phone, subscribeInfo.getPhone());
  assertEquals(Status.BAD_STATUS, subscribeInfo.getStatus());
  }
}

В режиме отладки в логах я вижу транзакцию, запущенную и откаченную

INFO: Began transaction (1): transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@1edd9b3]; rollback [true]
[main] DEBUG org.hibernate.SQL - insert into sms_subscribe (phone_cell, status, ts_subscribe, subscription_status, ts_unsubscribe, receiverIdentification, user_id) values (?, ?, ?, ?, ?, ?, ?) 
INFO: Rolled back transaction after test execution for test context [[TestContext@1f18cbe testClass = GenerateCodeStrategyTest, locations = array<String>['classpath:/applicationContext.xml'], testInstance = lv.mrb.server.service.GenerateCodeStrategyTest@14f1726, testMethod = genCodeIntegrationTestCommunicationFailure@GenerateCodeStrategyTest, testException = [null]]]

Может быть, у кого-то есть идея, почему это происходит? Спасибо за помощь.

ОБНОВЛЕНИЕ: Этот интеграционный тест генерирует некоторые параметры, затем с помощью Mockito макет объекта сеанса вставляется в сервис Strategy. Этот фиктивный объект просто вызывает исключение, и в этом исключении данные службы Стратегии сохраняются в базе данных через слой DAO. Затем проверьте выполнение запроса к базе данных через слой DAO и подтвердите сохраненные значения.

Данные сохраняются через Hibernate, поэтому в моем объекте DAO объект сохраняется таким образом

final Session currentSession = sessionFactory.getCurrentSession();
currentSession.save(object);

sessionFactory - это AnnotationSessionFactoryBean, где источником данных является c3p0 ComboPooledDataSource class

ОБНОВЛЕНИЕ 2: Проблема была с движком Mysql, по умолчанию это был MyISAM, поэтому мне просто нужно было переключить его на InnoDB, и теперь все работает.

Ответы [ 2 ]

4 голосов
/ 09 мая 2011

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

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

0 голосов
/ 29 сентября 2017

Попробуйте удалить @Transactional аннотацию с уровня класса и оставить ее только для определенных методов тестирования.

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

...