2009-06-09 203 views
2

我想使用SpringContextTests測試我的Dao類。
在我的方法類中,我擴展了AbstractTransactionalJUnit4SpringContextTests以便我的測試類與JUnit4集成。我還設置了配置,並在@Before@After的tearDown中進行了初始化和數據庫清理。我的測試課完美運作。

我的問題是,當我運行我的測試類和數據庫填充數據時,原始數據沒有回滾,我的數據庫被清除。在@Before方法中,我清除數據庫並填充數據,認爲我將能夠回滾它,但不能。

任何人都可以訪問一個在數據庫中工作和回滾信息的例子。

附註:
我的測試方法中的每個數據庫操作都會回滾。但@Before方法中super.deleteFromTables("person")的執行沒有從數據庫中回滾所有以前的數據。

Spring會回滾所有的CRUD操作,但數據庫在事務不回滾之前會清理乾淨。春季交易管理測試

+0

如果在調試中放置'org.springframework.transaction',日誌輸出中是否有任何有趣的內容? – 2009-06-10 06:24:28

回答

2

感謝所有那些誰回答我的問題。我從這些答案中學到了很多東西,但它並沒有解決我的問題。
我知道我的測試數據做了一個事務管理,並且它的工作正常。
錯誤在我身上。

我忘記了關於數據庫命令的教訓,當您在DML語句後執行DDL語句時,它會自動提交事務。我在DML後執行了一個DDL,刪除了所有記錄,然後ALTERAUTO_INCREMENT表中的內容會導致自動提交併永久刪除表中的所有記錄。

解決我的問題解決我的問題。

0

避開你的問題,我建議你使用一個單獨的數據庫實例來運行你的測試。這樣,您可以安全地擦拭乾淨,並根據需要進行測試初始化​​。

據我所知,數據庫測試的Spring支持類只回滾測試中發生的情況,而不是在測試的設置和拆卸過程中發生的情況。

0

同意混淆 - 您應該針對自己的數據庫模式運行測試。

有了這個,你可以設置你的Hibernate屬性「創建降」:

隨着創建拖放,數據庫架構 會當 顯式關閉SessionFactory被丟棄。

參見:Optional Hibernate Config properites

例片段:

<bean id="sessionBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <props> 
     <prop key="hibernate.hbm2ddl.auto">create-drop</prop> 
     ...etc 
0

雖然我跟那傢伙的提示進行測試deciated分貝同意,沒有任何理由使用填充分貝不該在事務上下文中執行@Before和@After方法都不起作用,因此應該對其進行回滾。

候選條件:

  • 的數據建立在做的東西是不是事務性的(即DDL語句)
  • 東西在您的測試實際上是犯

你能後的交易@Before方法,我只是想知道你是在清理表還是實際刪除並重新創建它們?

+0

我使用Spring提供的測試機制。在我的`@ Before`方法中,`super.deleteFromTables(「members」);``super.executeSqlScript(「classpath:somescript.sql」,true);` – 2009-06-10 00:39:16

1

可能的原因:您正在使用的沒有正確的交易數據庫/數據庫引擎

  • ;
  • 您正在使用多個事務管理器和/或數據源,並且沒有找到正確的一個;
  • 你做你自己的,獨立的,交易在測試類

對於一個例子,這裏是一個(我的頭頂,沒有編譯)

public class DBTest extends AbstractTransactionalJUnit4SpringContextTests { 

    @Autowired 
    private SomeDAO _aBeanDefinedInMyContextFile; 

    @Test 
    public void insert_works() { 
     assert _aBeanDefinedInMyContextFile.findAll() == 0; 
     _aBeanDefinedInMyContextFile.save(new Bean()); 
     assert _aBeanDefinedInMyContextFile.findAll() == 1; 
    } 


} 

關鍵要點:

  • SomeDAO是一個接口,它對應於我的上下文中聲明的一個bean;
  • 該bean沒有任何事務性設置(建議/編程),它依賴於調用者是事務性的 - 無論是生產服務還是測試;
  • 該測試不包含任何事務管理代碼,因爲它全部在框架中完成。
+0

我的DAO實現擴展了Spring提供的SimpleJdbcDaoSupport,數據庫。我的DAO是否有交易管理代碼?如果我的DAO有事務管理,我該如何測試它? – 2009-06-10 00:47:44

0

至於我可以告訴大家,通過查看AbstractJUnit4SpringContextTests時和TransactionalTestExecutionListener的Javadoc和源代碼,你需要註釋你的測試方法,你想用transactionalised @Transactional。

還有@BeforeTransaction和@AfterTransaction註釋,您可以更好地控制事務中運行的內容。

我建議你用所有這些註釋創建註解的方法,包括@Before,然後用這些方法的斷點運行測試。這樣,您可以查看堆棧,並確定春天是否爲您啓動了交易。如果你在堆棧中看到類似「TransactionInterceptor」的東西,或者在名稱中有「Transaction」的東西,那麼很可能你正在進行一次交易。

1

我不確定你的班級有什麼問題。這裏是一個類的提取物,你想要用DbUnit和春季2.5什麼:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={ 
    "testContext.xml"}) 
@TransactionConfiguration 
@Transactional 
public class SampleDAOTest { 

    @Autowired 
    private DataSource dataSource; 
    @Autowired 
    private SampleDAO sampleDAO; 

    @Before 
    public void onSetUpInTransaction() throws Exception { 
     //Populate Test data 
     IDatabaseConnection dbUnitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource), "DATASOURCE"); 
      //read in from a dbunit excel file of test data 
     IDataSet dataSet = new XlsDataSet(new File("src/test/resources/TestData.xls")); 
     DatabaseOperation.INSERT.execute(dbUnitCon, dataSet); 
    } 


    @Test 
    public void testGetIntermediaryOrganisation() { 

     // Test getting a user 
     User object = sampleDAO.getUser(99L); 
     assertTrue(object.getValue); 


    } 
} 

一個這種方法的benfits的是,你不需要擴展任何類。所以你仍然可以擁有自己的測試層次結構。

如果您確實想堅持使用當前的方法而不是使用@before註釋,那麼您需要覆蓋下面的方法並將您的設置代碼放在那裏。

@Override 
public void onSetUpInTransaction() throws Exception {...} 

希望這有助於

0

你正在做tx中的@Before方法中的super.deleteFromTables。所以如果回滾tx不刪除也會回滾?