DbUnitをつかう3

DbUnitをつかう」というよりは「MySQLをつかう」になっているような気もしなくはないが…。


結局、ロールバックをしているのにもかかわらず変更が勝手にコミットされるのは、MySQLのEngineがMyISAMだったから、ということのようだ。
MyISAMトランザクションをサポートしていないから、ロールバックが効かないのは当然のことなのだった。
なお、AUTOCOMMITはどうやら今回の件に関係はなさそうだ。
AUTOCOMMIT=1であっても、明示的にトランザクションの発行を指示すれば複数の処理をCOMMITまたはROLLBACKできる。


というわけで最終的なテストクラスは以下のような形になった。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/applicationContext.xml")
@TransactionConfiguration
@Transactional
public class TestServiceImplTest extends DataSourceBasedDBTestCase {

	@Autowired
	private TestService service;
	@Autowired
	private TestDao dao;
	@Autowired
	private TransactionAwareDataSourceProxy dataSource;
	@PersistenceContext
	private EntityManager entityManager;
	
	@Override
	protected IDataSet getDataSet() throws Exception {
		return new XlsDataSet(new File("src/test/resources/com/yoshida/test/service/impl/TestServiceImplTest.xls"));
	}
	
	@Before
	public void setUp() throws Exception {
		super.setUp();
	}
	
	@After
	public void tearDown() throws Exception {
		super.tearDown();
	}
	
	@Test
	public void Springとの連携をテストする() {
		assertEquals(100, service.test());
	}

	@Test
	public void データベースからデータを取得してみる() throws ParseException {
		Employee employee = dao.getEmployeeByPk(1);
		assertEquals("山田電気", employee.getName());
		assertEquals(270000, employee.getSalary());
		assertEquals(new SimpleDateFormat("yyyyMMdd").parse("20090909"), employee.getEmploymentDay());
	}
	
	@Test
	public void データベースを更新してみる() throws Exception {
		// 更新
		Employee employee = new Employee();
		employee.setId(1);
		employee.setName("山田電気");
		employee.setEmploymentDay(new SimpleDateFormat("yyyyMMdd").parse("20090909"));
		employee.setSalary(300000);
		dao.mergeEmployee(employee);
		
		entityManager.flush();
		
		// 期待値
		IDataSet expectedDataSet = new XlsDataSet(new File("src/test/resources/com/yoshida/test/service/impl/TestServiceImplResult.xls"));
		ITable expectedTable = expectedDataSet.getTable("EMPLOYEE");
		// 実際値
		IDataSet actualDataSet  = getConnection().createDataSet();
		ITable actualTable = actualDataSet.getTable("EMPLOYEE");
		Assertion.assertEquals(expectedTable, actualTable);
	}

	@Override
	protected DataSource getDataSource() {
		return dataSource;
	}

entityManager.flush();を手動で行わなければならないのがJPAの悲しいところだ。
まあ、仕方がない。
ミソはTransactionAwareDataSourceProxyを使用しているところだが、この辺のことは他のサイトを参考にした方がいいと思うので書かない。
とにかく、やっと、できた!