- public class TestClass {
- @Test public void t1(){}
- }
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = { "classpath*:/spring1.xml", "classpath*:/spring2.xml" })
- @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
- @Transactional
- public class TestClass {
- @Inject
- //這個類會在執行時被注入,這裏是按類型注入,如果想按名稱注入,需要加上@Named註解,如@Named("class1")
- //實現類可以加上@Named("class1")註解,也可以是配置在配置文件中的
- Class1 class1;
- @Test
- public void t1(){}
- }
以下分別對使用到的幾個註解進行解釋:
@RunWith:這個是指定使用的單元測試執行類,這裏就指定的是SpringJUnit4ClassRunner.class;
@ContextConfiguration:這個指定Spring配置文件所在的路徑,可以同時指定多個文件;
@TestExecutionListeners:這個用於指定在測試類執行之前,可以做的一些動作,如這裏的DependencyInjectionTestExecutionListener.class,就可以對一測試類中的依賴進行注入,TransactionalTestExecutionListener.class用於對事務進行管理;這兩個都是Srping自帶的; 我們也可以實現自己的Listener類來完成我們自己的操作,只需要繼續類org.springframework.test.context.support.AbstractTestExecutionListener就可以了,具體可以參照DependencyInjectionTestExecutionListener.class的實現,後面我會貼出實例。 Listener實在實現類執行之前被執行、實現類的測試方法之前被執行,這與Listener的實現有關。
@Transactional:這裏的@Transactional不是必須的,這裏是和@TestExecutionListeners中的TransactionalTestExecutionListener.class配合使用,用於保證插入的數據庫中的測試數據,在測試完後,事務回滾,將插入的數據給刪除掉,保證數據庫的乾淨。如果沒有顯示的指定@Transactional,那麼插入到數據庫中的數據就是真實的插入了。
我們的單元測試,通常涉及到數據庫的操作,那我們就需要真實的從數據庫中讀取數據並進行邏輯處理,爲了保證數據庫的乾淨,也爲了保證測試數據的準確性與正確性,我們最好是在做測試之前插入我們自己準備的測試數據,然後在測試完成後,將數據刪除掉,這時我們就可以通過增加一個Listener,來準備我們需要的測試數據,並和上面的事務管理相結合,就不會真正的提交到數據庫中去了。
以下這個實例是一個簡單的Listener實現,只是功能是把我們配置在method上面的註解裏面的配置文件路徑給打印出來,因爲實現集成DBUnit並插入數據庫的代碼比較多,這裏我就不貼出來了。1.首先我們需要準備一個註解,用來標識其帶的參數爲測試準備的數據文件:DBUnitTestData.java
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- @Inherited
- @Documented
- public @interface DBUnitTestData {
- public String[] dataSetLocations();
- }
- import org.springframework.test.context.TestContext;
- import org.springframework.test.context.TestExecutionListener;
- public class DBUnitTestExecutionListener implements TestExecutionListener {
- public void prepareTestInstance(TestContext testContext) throws Exception {
- }
- public void beforeTestClass(TestContext testContext) throws Exception {
- // Nothing to do
- }
- public void afterTestClass(TestContext testContext) throws Exception {
- // Nothing to do
- }
- public void beforeTestMethod(TestContext testContext) throws Exception {
- DBUnitTestData dbUnitRefresh = testContext.getTestMethod().getAnnotation(DBUnitTestData.class);
- if (dbUnitRefresh == null) {
- return;
- }
- String[] dataSetLocations = dbUnitRefresh.dataSetLocations();
- loadTestData(testContext, dataSetLocations);
- }
- public void afterTestMethod(TestContext testContext) throws Exception {
- // Nothing to do
- }
- private void loadTestData(TestContext testContext, String[] dataSetLocations) {
- if (dataSetLocations == null || dataSetLocations.length == 0) {
- return;
- }
- for (String dataSetLocation : dataSetLocations) {
- //Do what you want to do with the data set files
- System.out.println(dataSetLocation);
- }
- }
- }
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = { "classpath*:/spring1.xml", "classpath*:/spring2.xml" })
- @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class,DBUnitTestExecutionListener.class })
- @Transactional
- public class TestClass {
- @Inject
- //這個類會在執行時被注入,這裏是按類型注入,如果想按名稱注入,需要加上@Named註解,如@Named("class1")
- //實現類可以加上@Named("class1")註解,也可以是配置在配置文件中的
- Class1 class1;
- @Test
- @DBUnitTestData(dataSetLocations={"classpath:/testData/testData1.xml","classpath:/testData/testData2.xml"})
- public void t1(){}
- }