您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > 第17章junit测试数据库访问
高效单元测试第17章测试数据库访问林若钦第四部分Junit扩展高效单元测试2本章内容:用mockobjects在隔离数据库的情况下进行单元测试用Cactus和DbUnit进行集成测试HSQLDB数据库DBUnit介绍DBUnit原理DbUnit测试基本概念和流程用DBUnit对HSQLDB数据库的测试高效单元测试3管理应用程序示例高效单元测试41.对数据库进行单元测试的介绍在前面我们描述了如何对JSP和filter进行单元测试,今天重点学习如何对JDBC组件进行单元测试。可以编写各种不同类型的包含数据库访问的测试对业务逻辑的单元测试对数据库访问的单元测试数据库集成单元测试高效单元测试52.隔离开数据库测试业务逻辑目标是对不包含数据库访问代码的业务逻辑代码进行单元测试。尽管这种测试本质上说不是数据库测试,但它却是独立的测试那些难以测试的数据库代码的一个很好的策略。将数据库的访问层和业务逻辑层分开的话,这项工作将变得非常的简单。让我们看看这意味着什么。AdminServlet的定义如下:。高效单元测试6importjava.util.Collection;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;publicclassAdminServletextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException{}publicStringgetCommand(HttpServletRequestrequest)throwsServletException{returnnull;}publicvoidcallView(HttpServletRequestrequest,HttpServletResponseresponse){}publicCollectionexecuteCommand(Stringcommand)throwsException{returnnull;}}高效单元测试72.1、实现数据库访问层的接口将此接口称为DataAccessManager,并把它的实现称为JdbcDataAccessManager。importjava.util.Collection;publicinterfaceDataAccessManager{Collectionexecute(Stringsql)throwsException;}高效单元测试82.1、实现数据库访问层的接口已经有了数据访问的接口,你需要重构类AdminServlet以使用该接口并实例化DataAccessManager的JdbcDataAccessManager的实现高效单元测试9重构的结果importjava.util.Collection;importjavax.naming.NamingException;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;publicclassAdminServlet1extendsHttpServlet{privateDataAccessManagerdataManager;publicvoidinit()throwsServletException{super.init();try{setDataAccessManager(newJdbcDataAccessManager());}catch(NamingExceptione){thrownewServletException(e);}}publicCollectionexecuteCommand(Stringcommand)throwsException{returnthis.dataManager.execute(command);}}现在为AdminServlet类的一个方法写一个单元测试就很简单了。所要做的就是建立一个DataAccessManager的mockobject实现。唯一需要技巧的地方就是决定如何将mock实例传给AdminServlet类以使AdminServlet类使用mock实现,而不是真实的JdbcDataAccessManager的实现。高效单元测试102.2建立一个模拟数据库接口可以采用多种策略来将一个DataAccessManager的mock传给AdminServlet:创建一个参数形式接受DataAccessManager接口的构造函数创建一个setter方法(setDataAccessManager(DataAccessManagermanager))派生AdminServlet类,重载executeCommand()在web.xml文件中定义一个作为AdminServlet初始化参数的类名,使数据访问管理器实现成为你的应用程序的参数高效单元测试11对于上面的方法,最好的方法就是使用setter方法了。所以,再次的将AdminServlet重构如下:publicclassAdminServlet2extendsHttpServlet{//[...]privateDataAccessManagerdataManager;publicDataAccessManagergetDataAccessManager(){returnthis.dataManager;}publicvoidsetDataAccessManager(DataAccessManagermanager){this.dataManager=manager;}publicvoidinit()throwsServletException{super.init();try{setDataAccessManager(newJdbcDataAccessManager());}catch(NamingExceptione){thrownewServletException(e);}}publicCollectionexecuteCommand(Stringcommand)throwsException{returnthis.dataManager.execute(command);}}高效单元测试122.3模拟数据库接口层publicclassTestAdminServletDynaMockextendsTestCase{publicvoidtestSomething()throwsException{MockmockManager=newMock(DataAccessManager.class);DataAccessManagermanager=(DataAccessManager)mockManager.proxy();mockManager.expectAndReturn(execute,C.ANY_ARGS,newArrayList());AdminServlet1servlet=newAdminServlet1();servlet.setDataAccessManager(manager);//Callthemethodtotesthere.Forexample://manager.doGet(request,response)//[...]}}首先用DynaMockAPI创建一个DataAccessManagermockobject,接下来当调用execute方法时让该mock返回一个空的ArrayList。接着要setDataAccessManager方法建立一个mock管理器。高效单元测试133.隔离开数据库测试持久性代码前面将业务层和数据访问层进行隔离测试,接下来,就将对数据访问层进行测试。下面,execute方法很简单。这种简单源于BeanUtils包的使用。BeanUtils提供了一个RowSetDynaClass,它封装了一个ResultSet并将数据库各列映射到bean属性中。然后就可以将各列作为属性用DynaBeanAPI来访问了。类RowSetDynaClass自动将ResultSet各列拷贝到dynabean的属性中,这就使得你可以在一结束初始化RowSetDynaClass对象后就关闭与数据库的链接。高效单元测试14JdbcDataAccessManager.javapublicclassJdbcDataAccessManagerimplementsDataAccessManager{privateDataSourcedataSource;publicJdbcDataAccessManager()throwsNamingException{this.dataSource=getDataSource();}protectedDataSourcegetDataSource()throwsNamingException{InitialContextcontext=newInitialContext();DataSourcedataSource=(DataSource)context.lookup(java:/DefaultDS);returndataSource;}protectedConnectiongetConnection()throwsSQLException{returnthis.dataSource.getConnection();}publicCollectionexecute(Stringsql)throwsException{Connectionconnection=getConnection();//Forsimplicity,we'llassume//theSQLisaSELECTqueryResultSetresultSet=connection.createStatement().executeQuery(sql);RowSetDynaClassrsdc=newRowSetDynaClass(resultSet);resultSet.close();connection.close();returnrsdc.getRows();}}高效单元测试15测试execute方法为execute方法写单元测试,就是对所有的JDBC的调用提供mock。首先,将一个mockConnection对象传递给JdbcDataAccessManager类。在这里,创建一个封装类。可以将getConnection方法定义为保护成员,接着创建一个派生自JdbcDataAccessManager的新类TestableJdbcDataAccessManager。并添加setter方法,这样就绕过了DataSource而获得连接。高效单元测试16代码如下:publicclassTestableJdbcDataAccessManagerextendsJdbcDataAccessManager{privateConnectionconnection;publicTestableJdbcDataAccessManager()throwsNamingException{super();}publicvoidsetConnection(Connectionconnection){this.connection=connection;}protectedConnectiongetConnection()throwsSQLException{returnthis.connection;}prot
本文标题:第17章junit测试数据库访问
链接地址:https://www.777doc.com/doc-2153754 .html