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を使用しているところだが、この辺のことは他のサイトを参考にした方がいいと思うので書かない。
とにかく、やっと、できた!