Spring との統合テストに関する多くの投稿やスレッドを読みましたが、満足できるものも役立つものもありません。
Hibernate、Spring Data、および Oracle データベースで Spring 3.2.3 を使用しています。テストには、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());
}
}
私が見つけたのは@Transactional(propagation=Propagation.REQUIRES_NEW)
、テストで NewsService に注釈を付けると正常に動作するということですが、本番モードとは異なります。@Transactional(propagation=Propagation.REQUIRED)
DbUnit-Spring-test はそれ自体でトランザクションを開き、トランザクションがまだコミットされていないため、後者のアサートは失敗するため、十分ではありません。最後のアサートが実行される前にトランザクションがコミットされるようにするにはどうすればよいですか?