act*_*ctc 6 spring transactions spring-test-dbunit
我已经阅读了许多有关使用Spring进行集成测试的帖子和主题,但是没有什么令人满意或有用的。
我们将Spring 3.2.3与Hibernate,Spring Data和Oracle数据库一起使用。对于测试,我们还使用DbUnit和Spring-test-dbunit。在生产代码中,事务由控制器启动,服务本身对事务一无所知。
所以,这是我的测试:
@ContextConfiguration // ...
@ActiveProfiles // ...
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
ModifiedDbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = "oracleConnection")
@DatabaseSetup("/database/snapshot/snapshot.xml")
public class IntegrationTest extends AbstractTransactionalJUnit4SpringContextTests
{
@Test
public void sampleTest()
{
// transaction is already started
this.assertThatNewsContains(0);
News news1 = new News();
news1.setTitle("Test News 1");
News savedNews1 = this.newsService.save(news1);
Assert.assertTrue(savedNews1.getId() > 0);
News news2 = new News();
news2.setTitle("Test News 2");
News savedNews2 = this.newsService.save(news2);
Assert.assertTrue(savedNews2.getId() > 0);
News news3 = new News();
news3.setTitle("Test News 3");
News savedNews3 = this.newsService.save(news3);
Assert.assertTrue(savedNews3.getId() > 0);
// transaction commit should occur HERE
// @todo: HOW ?!
this.assertThatNewsContains(3);
}
private void assertThatNewsContains(int newsSize)
{
List<News> allNews = this.newsService.getNews();
Assert.assertEquals(newsSize, allNews.size());
}
}
Run Code Online (Sandbox Code Playgroud)
我发现的是,如果我用@Transactional(propagation=Propagation.REQUIRES_NEW)测试对NewsService进行注释可以正常工作,但是它与生产模式下并不相同。@Transactional(propagation=Propagation.REQUIRED)这是不够的,因为DbUnit-Spring-test本身会打开一个事务,而后者的断言将失败,因为该事务尚未提交。如何在执行最后一个断言之前实现事务已提交?
我终于设法在一个单独的事务中执行了一些代码。
你需要
@Autowired
private PlatformTransactionManager platformTransactionManager;
private TransactionTemplate transactionTemplate;
Run Code Online (Sandbox Code Playgroud)
在您的测试课中。然后,您可以执行以下操作:
this.transactionTemplate = new TransactionTemplate(this.platformTransactionManager);
// note that parameters passed to the transaction must be final!
final Object parameter = something;
Object returnedValue = this.transactionTemplate.execute(new TransactionCallback<Object>()
{
@Override
public Object doInTransaction(TransactionStatus status)
{
return doSomethingAndReturnAnObject(parameter);
}
}
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |