版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、高效單元測試 第17章 測試數(shù)據(jù)庫訪問 林若欽林若欽第四部分第四部分 Junit Junit擴展擴展高效單元測試2本章內(nèi)容:q用用mock objects在隔離數(shù)據(jù)庫的情況下進行單元在隔離數(shù)據(jù)庫的情況下進行單元測試測試q用用Cactus和和DbUnit進行集成測試進行集成測試qHSQLDB數(shù)據(jù)庫數(shù)據(jù)庫qDBUnit介紹介紹qDBUnit原理原理qDbUnit測試基本概念和流程測試基本概念和流程q用用 DBUnit 對對HSQLDB數(shù)據(jù)庫的測試數(shù)據(jù)庫的測試高效單元測試3管理應(yīng)用程序示例高效單元測試41.對數(shù)據(jù)庫進行單元測試的介紹 在前面我們描述了如何對在前面我們描述了如何對JSP和和filter
2、進行單元測試,進行單元測試,今天重點學(xué)習(xí)如何對今天重點學(xué)習(xí)如何對JDBC組件進行單元測試。組件進行單元測試??梢跃帉懜鞣N不同類型的包含數(shù)據(jù)庫訪問的測試可以編寫各種不同類型的包含數(shù)據(jù)庫訪問的測試n對業(yè)務(wù)邏輯的單元測試對業(yè)務(wù)邏輯的單元測試 n對數(shù)據(jù)庫訪問的單元測試對數(shù)據(jù)庫訪問的單元測試 n數(shù)據(jù)庫集成單元測試數(shù)據(jù)庫集成單元測試高效單元測試52.隔離開數(shù)據(jù)庫測試業(yè)務(wù)邏輯隔離開數(shù)據(jù)庫測試業(yè)務(wù)邏輯 n目標(biāo)是對不包含數(shù)據(jù)庫訪問代碼的業(yè)務(wù)邏輯代碼進行單元測試。n盡管這種測試本質(zhì)上說不是數(shù)據(jù)庫測試,但它卻是獨立的測試那些難以測試的數(shù)據(jù)庫代碼的一個很好的策略。n將數(shù)據(jù)庫的訪問層和業(yè)務(wù)邏輯層分開的話,這項工作將變得
3、非常的簡單。n讓我們看看這意味著什么。AdminServlet的定義如下: 。 高效單元測試6import java.util.Collection;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class AdminServlet extends HttpServlet public void
4、doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException public String getCommand(HttpServletRequest request) throws ServletException return null;public void callView(HttpServletRequest request, HttpServletResponse response) public Collection executeCommand(String comma
5、nd) throws Exception return null;高效單元測試72.1、實現(xiàn)數(shù)據(jù)庫訪問層的接口、實現(xiàn)數(shù)據(jù)庫訪問層的接口 n將此接口稱為DataAccessManager,并把它的實現(xiàn)稱為JdbcDataAccessManager。import java.util.Collection;public interface DataAccessManager Collection execute(String sql) throws Exception;高效單元測試82.1、實現(xiàn)數(shù)據(jù)庫訪問層的接口、實現(xiàn)數(shù)據(jù)庫訪問層的接口已經(jīng)有了數(shù)據(jù)訪問的接口,你需要重構(gòu)類AdminServlet以使
6、用該接口并實例化DataAccessManager的JdbcDataAccessManager的實現(xiàn) 高效單元測試9重構(gòu)的結(jié)果import java.util.Collection;import javax.naming.NamingException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;public class AdminServlet1 extends HttpServlet private DataAccessManager dataManager;public void
7、init() throws ServletException super.init();try setDataAccessManager(new JdbcDataAccessManager(); catch (NamingException e) throw new ServletException(e);public Collection executeCommand(String command) throws Exception return this.dataManager.execute(command);現(xiàn)在為現(xiàn)在為AdminServlet類的一類的一個方法寫一個單元測試就很簡個方
8、法寫一個單元測試就很簡單了。所要做的就是建立一個單了。所要做的就是建立一個DataAccessManager的的mock object實現(xiàn)。唯一需要實現(xiàn)。唯一需要技巧的地方就是決定如何將技巧的地方就是決定如何將mock實例傳給實例傳給AdminServlet類以使類以使AdminServlet類使用類使用mock實現(xiàn),而不是真實的實現(xiàn),而不是真實的JdbcDataAccessManager的的實現(xiàn)。實現(xiàn)。 高效單元測試102.2 建立一個模擬數(shù)據(jù)庫接口建立一個模擬數(shù)據(jù)庫接口可以采用多種策略來將一個可以采用多種策略來將一個DataAccessManager的的mock 傳給傳給AdminServ
9、let:q創(chuàng)建一個參數(shù)形式接受創(chuàng)建一個參數(shù)形式接受DataAccessManager接口的構(gòu)接口的構(gòu)造函數(shù)造函數(shù) q創(chuàng)建一個創(chuàng)建一個setter方法(方法(setDataAccessManager(DataAccessManager manager) q派生派生AdminServlet類,重載類,重載executeCommand()() q在在web.xml文件中定義一個作為文件中定義一個作為AdminServlet初始化初始化參數(shù)的類名,使數(shù)據(jù)訪問管理器實現(xiàn)成為你的應(yīng)用程序參數(shù)的類名,使數(shù)據(jù)訪問管理器實現(xiàn)成為你的應(yīng)用程序的參數(shù)的參數(shù)高效單元測試11對于上面的方法,最好的方法就是使用sette
10、r方法了。所以,再次的將AdminServlet重構(gòu)如下 :public class AdminServlet2 extends HttpServlet / . private DataAccessManager dataManager; public DataAccessManager getDataAccessManager() return this.dataManager; public void setDataAccessManager(DataAccessManager manager) this.dataManager = manager; public void init()
11、throws ServletException super.init(); try setDataAccessManager(new JdbcDataAccessManager(); catch (NamingException e) throw new ServletException(e); public Collection executeCommand(String command) throws Exception return this.dataManager.execute(command); 高效單元測試122.3 模擬數(shù)據(jù)庫接口層模擬數(shù)據(jù)庫接口層 public class T
12、estAdminServletDynaMock extends TestCase public void testSomething() throws Exception Mock mockManager = new Mock(DataAccessManager.class);DataAccessManager manager = (DataAccessManager) mockMxy();mockManager.expectAndReturn(execute, C.ANY_ARGS, new ArrayList();AdminServlet1 servlet = new
13、AdminServlet1();servlet.setDataAccessManager(manager);/ Call the method to test here. For example:/ manager.doGet(request, response)/ .首先用首先用DynaMock API創(chuàng)建一個創(chuàng)建一個DataAccessManager mock object,接下來當(dāng)調(diào)用接下來當(dāng)調(diào)用execute方法時讓該方法時讓該mock返回一個空的返回一個空的ArrayList。接著。接著要要setDataAccessManager方法建立一個方法建立一個mock管理器。管理器。高效單
14、元測試133.隔離開數(shù)據(jù)庫測試持久性代碼隔離開數(shù)據(jù)庫測試持久性代碼 n前面將業(yè)務(wù)層和數(shù)據(jù)訪問層進行隔離測試,接下來,就將前面將業(yè)務(wù)層和數(shù)據(jù)訪問層進行隔離測試,接下來,就將對數(shù)據(jù)訪問層進行測試。對數(shù)據(jù)訪問層進行測試。 n下面,下面,execute方法很簡單。這種簡單源于方法很簡單。這種簡單源于BeanUtils包包的使用。的使用。BeanUtils提供了一個提供了一個RowSetDynaClass,它,它封裝了一個封裝了一個ResultSet并將數(shù)據(jù)庫各列映射到并將數(shù)據(jù)庫各列映射到bean屬性中屬性中。然后就可以將各列作為屬性用。然后就可以將各列作為屬性用DynaBean API來訪問了來訪問了
15、。n 類類RowSetDynaClass自動將自動將ResultSet各列拷貝到各列拷貝到dyna bean的屬性中,這就使得你可以在一結(jié)束初始化的屬性中,這就使得你可以在一結(jié)束初始化RowSetDynaClass對象后就關(guān)閉與數(shù)據(jù)庫的鏈接。對象后就關(guān)閉與數(shù)據(jù)庫的鏈接。高效單元測試14JdbcDataAccessManager.javapublic class JdbcDataAccessManager implements DataAccessManager private DataSource dataSource;public JdbcDataAccessManager() throws
16、 NamingException this.dataSource = getDataSource();protected DataSource getDataSource() throws NamingException InitialContext context = new InitialContext();DataSource dataSource = (DataSource) context.lookup(java:/DefaultDS);return dataSource;protected Connection getConnection() throws SQLException
17、 return this.dataSource.getConnection();public Collection execute(String sql) throws Exception Connection connection = getConnection(); / For simplicity, well assume/ the SQL is a SELECT queryResultSet resultSet = connection.createStatement().executeQuery(sql);RowSetDynaClass rsdc = new RowSetDynaCl
18、ass(resultSet);resultSet.close();connection.close();return rsdc.getRows();高效單元測試15測試測試execute方法方法 為為execute方法寫單元測試,就是對所有的方法寫單元測試,就是對所有的JDBC的的調(diào)用提供調(diào)用提供mock。首先,將一個首先,將一個mock Connection對象傳遞給對象傳遞給JdbcDataAccessManager類。在這里,創(chuàng)建一類。在這里,創(chuàng)建一個封裝類??梢詫€封裝類。可以將getConnection方法定義為保方法定義為保護成員,接著創(chuàng)建一個派生自護成員,接著創(chuàng)建一個派生自Jdb
19、cDataAccessManager 的新類的新類TestableJdbcDataAccessManager。并添加。并添加setter方法,這樣就繞過了方法,這樣就繞過了DataSource而獲得連而獲得連接。接。高效單元測試16 代碼如下:public class TestableJdbcDataAccessManager extends JdbcDataAccessManager private Connection connection;public TestableJdbcDataAccessManager() throws NamingException super();publi
20、c void setConnection(Connection connection) this.connection = connection;protected Connection getConnection() throws SQLException return this.connection;protected DataSource getDataSource() throws NamingException return null;高效單元測試17 創(chuàng)建第一個測試創(chuàng)建第一個測試 現(xiàn)在有了自己的方式來編寫execute方法,所以,開始為它編寫第一個測試程序。對于任何使用mocks的
21、測試來說,困難的地方在于找到那些需要模擬的方法。換句話說,為了提供模擬的響應(yīng)必須準(zhǔn)確的理解API的哪些方法將被調(diào)用。通常,可以嘗試犯些錯誤,接著測試運行,一步步重構(gòu)。 高效單元測試18TestJdbcDataAccessManagerMO1public class TestJdbcDataAccessManagerMO1 extends TestCase private MockStatement statement;private MockConnection2 connection;private TestableJdbcDataAccessManager manager;protecte
22、d void setUp() throws Exception statement = new MockStatement(); connection = new MockConnection2(); /創(chuàng)建Statement和Connection mock objects connection.setupStatement(statement); /讓Connection mock 返回mock Statement對象/實例化該封裝類,并調(diào)用setConnection()方法來傳遞mock Connection對象manager = new TestableJdbcDataAccessMan
23、ager();manager.setConnection(connection);public void testExecuteOk() throws Exception String sql = SELECT * FROM CUSTOMER; Collection result = manager.execute(sql);/ 調(diào)用方法進行單元測試 Iterator beans = result.iterator(); assertTrue(beans.hasNext(); /通過返回的Collection來判斷結(jié)果 DynaBean bean1 = (DynaBean) beans.nex
24、t(); assertEquals(John, bean1.get(firstname); assertEquals(Doe, bean1.get(lastname); assertTrue(!beans.hasNext(); 這個程序并沒有結(jié)束,你會發(fā)現(xiàn)一個這個程序并沒有結(jié)束,你會發(fā)現(xiàn)一個錯誤,你還沒有告訴但錯誤,你還沒有告訴但executeQuery方法被調(diào)用時方法被調(diào)用時mock Statement應(yīng)該返應(yīng)該返回些什么!回些什么! 高效單元測試19改進該測試改進該測試 public class TestJdbcDataAccessManagerMO2 extends TestCase p
25、rivate MockSingleRowResultSet resultSet;private MockStatement statement;private MockConnection2 connection;private TestableJdbcDataAccessManager manager;protected void setUp() throws Exception resultSet = new MockSingleRowResultSet();statement = new MockStatement();connection = new MockConnection2()
26、;connection.setupStatement(statement);manager = new TestableJdbcDataAccessManager();manager.setConnection(connection);public void testExecuteOk() throws Exception String sql = SELECT * FROM CUSTOMER;statement.addExpectedExecuteQuery(sql, resultSet);String columnsLowercase = new String firstname, las
27、tname ;resultSet.addExpectedNamedValues(columnsLowercase, new Object John, Doe );Collection result = manager.execute(sql);Iterator beans = result.iterator();assertTrue(beans.hasNext();DynaBean bean1 = (DynaBean) beans.next();assertEquals(John, bean1.get(firstname);assertEquals(Doe, bean1.get(lastnam
28、e);assertTrue(!beans.hasNext();這里使用了這里使用了MockSingeRowResultSet實現(xiàn)。實現(xiàn)。MockO提供了兩種實現(xiàn),提供了兩種實現(xiàn),MockSingleRowResultSet和和MockMultiRowResultSet。顧名思義顧名思義:第一種是用來模擬只有一行的第一種是用來模擬只有一行的ResultSet,而第二種方法模擬具有多行的情況。,而第二種方法模擬具有多行的情況。該測試同樣失敗了。該測試同樣失敗了。高效單元測試20重構(gòu)后的進一步測試還是發(fā)生了錯誤,進一步的研究發(fā)現(xiàn),在類RowSetDynaClass實例化時調(diào)用了introspect。
29、這樣的錯誤說明了使用mocks一個潛在的問題:需要對調(diào)用mock的類的實現(xiàn)有較深的了解。正如剛剛展示的,可以通過調(diào)試發(fā)現(xiàn)對mock的間接調(diào)用。還有另外的兩種解決方法:獲得訪問源碼的權(quán)限,或者是在不同的層次上進行模擬。高效單元測試21在源碼中發(fā)現(xiàn)間接調(diào)用獲取源碼通常是不可行的,而且會浪費大量的時間。采用最多的方法就是在不同的層次進行模擬了。這里需要測試的是execute方法而不是類RowSetDynaClass類。一個辦法就是創(chuàng)建一個mock RowSetDynaClass并將它以某種方法傳遞給execute方法。 在這個例子中看起來額外的建立兩個方法(getMetaData和getColumn
30、Count)更容易些。但是,當(dāng)要給定的測試fixture變得長而復(fù)雜時,通常采用的方法就是在不同層次上進行。但使用mock時,如果待測之前需要設(shè)置的步數(shù)太多,就應(yīng)當(dāng)考慮重構(gòu)了。高效單元測試22改正測試改正了test case使得它支持對getMetaData和getColumnCount的調(diào)用。高效單元測試23public class TestJdbcDataAccessManagerMO3 extends TestCase private MockSingleRowResultSet resultSet;private MockStatement statement;private Mock
31、Connection2 connection;private TestableJdbcDataAccessManager manager;private MockResultSetMetaData resultSetMetaData;protected void setUp() throws Exception resultSetMetaData = new MockResultSetMetaData();resultSet = new MockSingleRowResultSet();resultSet.setupMetaData(resultSetMetaData);statement =
32、 new MockStatement();connection = new MockConnection2();connection.setupStatement(statement);manager = new TestableJdbcDataAccessManager();manager.setConnection(connection);public void testExecuteOk() throws Exception String sql = SELECT * FROM CUSTOMER;statement.addExpectedExecuteQuery(sql, resultS
33、et);String columnsLowercase = new String firstname, lastname ;String columnsUppercase = new String FIRSTNAME, LASTNAME ;String columnClasseNames = new String String.class.getName(),String.class.getName() ;resultSetMetaData.setupAddColumnNames(columnsUppercase);resultSetMetaData.setupAddColumnClassNa
34、mes(columnClasseNames);resultSetMetaData.setupGetColumnCount(2);resultSet.addExpectedNamedValues(columnsLowercase, new Object John, Doe );Collection result = manager.execute(sql);Iterator beans = result.iterator();assertTrue(beans.hasNext();DynaBean bean1 = (DynaBean) beans.next();assertEquals(John,
35、 bean1.get(firstname);assertEquals(Doe, bean1.get(lastname);assertTrue(!beans.hasNext();高效單元測試243.2 用預(yù)期驗證狀態(tài)經(jīng)過上面的改動以后,還需要驗證測試部分的斷言。 1.驗證數(shù)據(jù)庫被正確的關(guān)閉 2.查詢串是否是測試中傳遞的那個 3.PreparedStatement僅創(chuàng)建一次對此,我們使用預(yù)期(調(diào)用各自的verify())高效單元測試25添加預(yù)期添加預(yù)期public class TestJdbcDataAccessManagerMO4 extends TestCase private MockSin
36、gleRowResultSet resultSet;private MockResultSetMetaData resultSetMetaData;private MockStatement statement;private MockConnection2 connection;private TestableJdbcDataAccessManager manager;protected void setUp() throws Exception resultSetMetaData = new MockResultSetMetaData();resultSet = new MockSingl
37、eRowResultSet();resultSet.setupMetaData(resultSetMetaData);statement = new MockStatement();connection = new MockConnection2();connection.setupStatement(statement);manager = new TestableJdbcDataAccessManager();manager.setConnection(connection);protected void tearDown() / 驗證設(shè)置了預(yù)期驗證設(shè)置了預(yù)期connection.veri
38、fy();statement.verify();resultSet.verify();public void testExecuteOk() throws Exception String sql = SELECT * FROM CUSTOMER;statement.addExpectedExecuteQuery(sql, resultSet);/ 驗證正在被執(zhí)行驗證正在被執(zhí)行的的SQL就是我們傳遞的就是我們傳遞的String columnsUppercase = new String FIRSTNAME, LASTNAME ;String columnsLowercase = new Str
39、ing firstname, lastname ;String columnClasseNames = new String String.class.getName(),String.class.getName() ;resultSetMetaData.setupAddColumnNames(columnsUppercase);resultSetMetaData.setupAddColumnClassNames(columnClasseNames);resultSetMetaData.setupGetColumnCount(2);resultSet.addExpectedNamedValue
40、s(columnsLowercase, new Object John, Doe );connection.setExpectedCreateStatementCalls(1);/ 驗證僅創(chuàng)建了一個驗證僅創(chuàng)建了一個Statementconnection.setExpectedCloseCalls(1);/ 驗證驗證close方法被調(diào)用了一次方法被調(diào)用了一次Collection result = manager.execute(sql);Iterator beans = result.iterator();assertTrue(beans.hasNext();DynaBean bean1 = (
41、DynaBean) beans.next();assertEquals(John, bean1.get(firstname);assertEquals(Doe, bean1.get(lastname);assertTrue(!beans.hasNext();高效單元測試26對錯誤的測試在測試的過程中,時常會產(chǎn)生如下的清單。 getConnection方法可能會失敗并產(chǎn)生一個SQLException的異常 Statement的創(chuàng)建可能會失敗 查詢的執(zhí)行可能失敗這些錯誤有的時候很隱晦,除了Bug報告,只能憑借經(jīng)驗。例如在測試數(shù)據(jù)庫的時候,一個比較典型的錯誤就是出現(xiàn)異常時沒有關(guān)閉數(shù)據(jù)庫的連接。高效單
42、元測試27public void testExecuteCloseConnectionOnException() throws Exception String sql = SELECT * FROM CUSTOMER;statement.setupThrowExceptionOnExecute(new SQLException(sql error);connection.setExpectedCloseCalls(1);try manager.execute(sql);fail(Should have thrown a SQLException); catch (SQLException e
43、xpected) assertEquals(sql error, expected.getMessage();為了配合工作和維護代碼的嚴(yán)密性,你需要在為了配合工作和維護代碼的嚴(yán)密性,你需要在JdbcDataManager.java中使用中使用try/finally語句語句高效單元測試28JdbcDataAccessManager2public class JdbcDataAccessManager2 implements DataAccessManager private DataSource dataSource;public JdbcDataAccessManager2() throws
44、NamingException this.dataSource = getDataSource();protected DataSource getDataSource() throws NamingException InitialContext context = new InitialContext();DataSource dataSource = (DataSource) context.lookup(java:comp/env/jdbc/DefaultDS);return dataSource;protected Connection getConnection() throws
45、SQLException return this.dataSource.getConnection();public Collection execute(String sql) throws Exception ResultSet resultSet = null;Connection connection = null;Collection result = null;try connection = getConnection();/ For simplicity, well assume the SQL is a SELECT /query resultSet = connection
46、.createStatement().executeQuery(sql);RowSetDynaClass rsdc = new RowSetDynaClass(resultSet);result = rsdc.getRows(); finally if (resultSet != null) resultSet.close();if (connection != null) connection.close();return result;這就是隔離開數(shù)據(jù)庫測試持久性代碼的過程高效單元測試29 HSQLDB數(shù)據(jù)庫簡介數(shù)據(jù)庫簡介1. HSQLDB是一個開放源代碼的JAVA數(shù)據(jù)庫,其具有標(biāo)準(zhǔn)的SQ
47、L語法和JAVA接口,它可以自由 使用和分發(fā),非常簡潔和快速的。具有SERVER模式,進程內(nèi)模式(IN-PROCESS)和內(nèi)存模式 (MEMORY-ONLY)三種。運行HSQLDB需要HSQLDB.JAR包, 它包含了一些組件和程序。每個程序需 要 不同的命令來運行。它位于項目的LIB目錄下,目前的版本是2.2.5。 2. HSQLDB所涉及的一些文件:每個HSQLDB數(shù)據(jù)庫包含了2到5個命名相同但擴展名不同的文件, 這些文件位于同一個目錄下。例如,名位“TEST”的數(shù)據(jù)庫包含了以下幾個文件: -TEST.PROPERTIES /PROPERTIES文件描述了數(shù)據(jù)庫的基本配置 -TEST.SC
48、RIPT /SCRIPT文件記錄了表和其它數(shù)據(jù)庫對象的定義 -TEST.LOG /LOG文件記錄了數(shù)據(jù)庫最近所做的更新 -TEST.DATA /DATA文件包含了CACHED(緩沖)表的數(shù)據(jù) -TEST.BACKUP /BACKUP文件是將DATA文件壓縮備份,它包含了DATA文件上次的最終狀態(tài)數(shù)據(jù). 所有這些文件都是必不可少的,千萬不可擅自刪除。但如果你的數(shù)據(jù)庫沒有緩沖表(CACHED TABLE),TEST.DATA和TEST.BACKUP文件是不會存在。3. HSQLDB包括SERVER、 IN-PROCESS和MEMRY-ONLY三種模式,本文主要介紹如何使用SERVER模式。 SER
49、VER模式:這種模式是首選的也是最快的。它采用HSQLDB專有的通信協(xié)議。啟動服務(wù)器需要編寫批處理命令。HSQLDB提供的所有工具都能以JAVA CLASS歸檔文件(也就是JAR)的標(biāo)準(zhǔn)方式運行。高效單元測試303.在在JAVA PROJET建立建立MYCCIT項目將項目將HSQLDB.JAR導(dǎo)入項目導(dǎo)入項目LIB下,如圖所示:下,如圖所示:高效單元測試31HSQLDB的使用的使用1. 編寫啟動服務(wù)器批處理命令編寫啟動服務(wù)器批處理命令。 (1)在HSQLDB_1_8_0_10.ZIP解壓的文件夾HSQLDB中創(chuàng)建一MYHSQLDB文件夾(文件名自定義), 再在MYHSQLDB文件夾創(chuàng)建一個RU
50、NMYHSQLDB.BAT文件,名稱自定義,將 java -cp ./lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 myhsqldb寫入文件中保存。(注:需要將HSQLDB.JAR導(dǎo)入到項目的LIB下。) LIB:對應(yīng)項目下面的LIB。 ORG.HSQLDB.SERVER:驅(qū)動類。 DATABASE.0 、 DBNAME.0:因為服務(wù)模式運行的時候可以指定10個數(shù)據(jù)庫,如有多個數(shù) 據(jù) 庫,則繼續(xù)寫命令行參數(shù) DATABASE.1 、 DBNAME.1等。 MYDB :啟動服務(wù)器的命令(即BAT文件)啟動了帶有一個(默認(rèn)為
51、一個數(shù)據(jù)庫)數(shù)據(jù)庫 的服務(wù)器,這個數(shù)據(jù)庫是一個名為“MYDB.*”文件,這些文件就是MYDB.PROPERTIES、 MYDB.SCRIPT、MYDB.LOG等文件。 MYHSQLDB: 是MYDB的別名,可在連接數(shù)據(jù)庫時使用。 (2)執(zhí)行RUNMYHSQLDB.BAT文件,將生成MYDB.PROPERTIES和MYDB.LOG文件。 (3) 在MYHSQLDB文件夾中創(chuàng)建一個UIMYHSQLDB.BAT文件,名稱自定義,將 java -cp .libhsqldb.jar org.hsqldb.util.DatabaseManager -url jdbc:hsqldb:hsql:/127.0.
52、0.1:9001/ myhsqldb 寫入文件中并保存。 ORG.HSQLDB.UTIL.DATABASEMANAGER:數(shù)據(jù)庫管理類。 JDBC:HSQLDB:HSQL:/:9001/MYHSQLDB :連接數(shù)據(jù)庫驅(qū)動的URL。高效單元測試32(4)執(zhí)行UIMYHSQLDB.BAT文件,將彈出如下窗體: 高效單元測試332.初始化初始化CUSTOMER、INVOICE、PRODUCT三張表三張表 高效單元測試343.給給MYHSQLDB創(chuàng)建創(chuàng)建USER表表 高效單元測試354.在項目中添加連數(shù)據(jù)庫接驅(qū)動類在項目中添加連數(shù)據(jù)庫接驅(qū)動類JDBCDAO類和類和TESTHSQLDB
53、測試類。測試類。高效單元測試365. JDBCDAO類有連個方法:類有連個方法: GETCONN()和和CLOSEALL( CONNECTION CONN, PREPAREDSTATEMENT PSTMT, RESULTSET RS )方法。方法。 (1) GETCONN()方法。 高效單元測試37(2)CLOSEALL( CONNECTION CONN, PREPAREDSTATEMENT PSTMT, RESULTSET RS )方法。 高效單元測試385. TESTHSQLDB測試類,為測試類,為USER添加一條記錄添加一條記錄高效單元測試396.運行運行TESTHSQLDB測試類,查看
54、控制臺輸出,添加用戶成功測試類,查看控制臺輸出,添加用戶成功高效單元測試407.輸入查詢輸入查詢SQL語句,查詢語句,查詢USER信息(創(chuàng)建用戶信息(創(chuàng)建用戶WUMINGTUO成功)成功) 高效單元測試411、DBUnit介紹介紹dbunit是一個基于junit擴展的數(shù)據(jù)庫測試框架。它提供了大量的類對與數(shù)據(jù)庫相關(guān)的操作進行了抽象和封裝。它通過使用用戶自定義的數(shù)據(jù)集以及相關(guān)操作使數(shù)據(jù)庫處于一種可知的狀態(tài),從而使得測試自動化、可重復(fù)和相對獨立。 高效單元測試42n為依賴于其他外部系統(tǒng)(如數(shù)據(jù)庫或其他接口)的代碼編寫單元測試是一件很困難的工作。在這種情況下,有效的單元必須隔離測試對象和外部依賴,以便管理測試對象的狀態(tài)和行為。 n使用mock object對象,是隔離外部依賴的一個有效方法。如果我們的測試對象是依賴于DAO的代碼,mock object技術(shù)很方便。但如果測試對象變成了DAO本身,又如何進行單元測試呢? n開源的DbUnit項目,為以上的問題提供了一個相當(dāng)優(yōu)雅的解決方案。使用DbUnit,開發(fā)人員可以控
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 臺階課文教學(xué)課件
- 四季之美課件77
- 收到以物抵債的設(shè)備賬務(wù)處理實例-記賬實操
- 國際金融教案
- 小學(xué)硬筆書法課件教學(xué)
- 智慧物流園解決方案
- 2023年農(nóng)業(yè)航空作業(yè)裝置項目評價分析報告
- 2024年破傷風(fēng)類毒素項目評估分析報告
- 采購合同管理自查報告
- 畢業(yè)生就業(yè)協(xié)議書學(xué)前教育
- 125碘粒子知情同意書
- 各系統(tǒng)調(diào)試報告
- 英語人稱代詞-物主代詞-名詞所有格(共4頁)
- 幕墻工程量自動計算結(jié)果表格
- 海灣控制器CAN總線聯(lián)網(wǎng)調(diào)試說明(共26頁)
- 《質(zhì)量管理體系文件》ISO9001_2015_中英文對照
- 漂流項目規(guī)劃設(shè)計書
- 中國花鳥畫各個時期藝術(shù)特點探析
- 第四章微量元素地球化學(xué)
- [精華]^門羅第2本書中文《魂魄出體》FarJourneys
- 木霉菌生防綜述
評論
0/150
提交評論