用Dunit测试 BPL方式实现的数据库连接池实战开发

用Dunit测试 BPL方式实现的数据库连接池实战开发 

 
DELPHI实现的三层数据连接池。

  声明IConnPoolWrapper 的接口。
  IConnPoolWrapper = interface(IInterface)
    ['{E08BDEB7-BCA3-4F24-AE2D-A8745ACE8708}']
    procedure SetConnectionString(connStr: String);
    procedure SetMaxConnections(maxConns: Integer);
    function GetMaxConnections: Integer;
    function GetConnection: TCustomConnection;
    function GetTotalConns: LongInt;
    procedure FreeConnection(aConnection: TCustomConnection);
    procedure InitConnectionPool(poolClass: String);
    function GetConnPoolKind: TConnPoolKind;
  end;
  具体的实现类实现。
  {$M+}
  TConnectionPoolWrapper = class(TPoolPersistentAdapter, IConnPoolWrapper)
    private
      ConnPoolFactory: TConnectionPoolFactory;
      ConnPool: TCustomConnectionPool;
    published
      procedure SetConnectionString(connStr: String);
      procedure SetMaxConnections(maxConns: Integer);
      function GetMaxConnections: Integer;
      function GetConnection: TCustomConnection;
      function GetTotalConns: LongInt;
      procedure FreeConnection(aConnection: TCustomConnection);
      procedure InitConnectionPool(poolClass: String);
      function GetConnPoolKind: TConnPoolKind;
    public
      constructor Create(poolClass: String);
      destructor Destroy; override;
  end;
{$M-}

//注册:
initialization
  RegisterClass(TConnectionPoolWrapper);

finalization
  UnRegisterClass(TConnectionPoolWrapper); 

constructor TConnectionPoolWrapper.Create(poolClass: String);
begin
  inherited Create;

  try
    ConnPoolFactory := TConnectionPoolFactory.Create;
    ConnPool := ConnPoolFactory.ConnectionPool(poolClass);
  finally
    ConnPoolFactory.Free;
  end;
end;

这里是一个工厂方法的调用。TADOConnectionPool, BDEPOOOL可以根据系统配置创建ADO或者是BDE的连接池。

新建一个package工程,把unit加进去。编译即可。
发布时只需发布
IConnPoolWrapper = interface(IInterface)
    ['{E08BDEB7-BCA3-4F24-AE2D-A8745ACE8708}']
    procedure SetConnectionString(connStr: String);
    procedure SetMaxConnections(maxConns: Integer);
    function GetMaxConnections: Integer;
    function GetConnection: TCustomConnection;
    function GetTotalConns: LongInt;
    procedure FreeConnection(aConnection: TCustomConnection);
    procedure InitConnectionPool(poolClass: String);
    function GetConnPoolKind: TConnPoolKind;
  end;
接口和编译好的BPL包即可使用。

现在利用Dunit建立一个DunitPoolTest工程。
Dpr单元的相应代码。
begin
  GUITestRunner.RunRegisteredTests;
end.

现在建立一个测试单元TestUnit; 这个测试单元是测试TconnectionPoolWrapper(代码)
另外再建一个TestBPLUnit单元,测试bpl包中的代码。
TTestCaseFirst = class(TTestCase)
    private
      adoWarpper : TConnectionPoolWrapper;  //要测试的类
    protected
      procedure SetUp; override;  //初始化类
      procedure TearDown; override;  //清除数据
    published
      procedure TestPoolisNull;
      procedure TestPoolKind;
      procedure TestPoolMaxConn;
      procedure TestPoolTotalConn;
 end;
上面有四个测试用例。


procedure SetUp; override;  //初始化类
这里可以做初始化信息,比如:加载参数,读取XML,创建TADOCONNECTION等。
procedure TearDown; override;  //清除数据
这里可以释放系统的资源。


procedure TTestCaseFirst.SetUp;
var
  pConnStr, pServerName,   pDBName,   pUser,  pPwd :string;
  i: Integer;
  dd: TConnPoolKind;
begin
  pServerName := '127.0.0.1';
  pDBName := 'Yktdata';
  pUser := 'sa';
  pPwd := '';
  pConnStr := 'Provider=SQLOLEDB.1;Persist Security Info=True;';
  pConnStr := pConnStr + 'Data Source=' + pServerName+'; Initial Catalog=' + pDBName;
  pConnStr := pConnStr + ';User ID='+ pUser +'; Password=' + pPwd;
  adoWarpper := TConnectionPoolWrapper.Create('');
  adoWarpper.SetConnectionString(pConnStr);
  adoWarpper.SetMaxConnections(3);
  //iWarpper.FreeConnection(conn);
 
end;

procedure TTestCaseFirst.TearDown;
begin
  FreeAndNil(adoWarpper);
end;

procedure TTestCaseFirst.TestPoolisNull;
var
  conn: TCustomConnection;
begin
  CoInitialize(nil);
  conn := adoWarpper.GetConnection;
  checkNotNull(conn, '获得数据库连接失败!');
  CoUninitialize;
end;

//测试adoconnection是否为空。
procedure TTestCaseFirst.TestPoolKind;
var
  conn: TCustomConnection;
begin
  CoInitialize(nil);
  conn := adoWarpper.GetConnection;
  CheckIS(conn, TADOConnection, '不是ADOConnection!');
  Check(connPoolADO = adoWarpper.GetConnPoolKind, '数据类型不是ConPoolDAO类型!');
  Check(connPoolBDE = adoWarpper.GetConnPoolKind, '数据类型不是ConPoolBDE类型!');
  CoUninitialize;
end;

//测试connpool连接类型是否为空。

procedure TTestCaseFirst.TestPoolMaxConn;
var
  conn: TCustomConnection;
  maxConn: Integer;
begin
  maxConn :=3;
  CoInitialize(nil);
  conn := adoWarpper.GetConnection;
  Check(maxConn = adoWarpper.GetMaxConnections , '最多数据库连接数大于!'+IntToStr(maxConn));
  {
  for maxConn:=1 to 10 do
    Check(maxConn < adoWarpper.GetMaxConnections , '最多数据库连接数大于!'+IntToStr(maxConn));
  }
  CoUninitialize;
end;
//最大数据库连接数测试:


procedure TTestCaseFirst.TestPoolTotalConn;
var
  conn: TCustomConnection;
  TotalConn: LongInt;
begin
  CoInitialize(nil);
  conn := adoWarpper.GetConnection;
  conn := adoWarpper.GetConnection;
  conn := adoWarpper.GetConnection;
 // conn := adoWarpper.GetConnection;
 
  for TotalConn:=1 to 10 do
    Check(TotalConn < adoWarpper.GetTotalConns , '当前数据库连接数大于!'+IntToStr(TotalConn));

  ShowMessage(IntToStr(adoWarpper.GetTotalConns));
  CoUninitialize;
end;

//当前最大数据库连接数测试:


bpl 测试和前面的相似,初始化时不同。

procedure TTestCaseBpl.SetUp;
var
  pConnStr, pServerName,   pDBName,   pUser,  pPwd :string;
  i: Integer;
  theClass             : TPersistentClass;
  thePlugin            : TPersistent;
  IPlug                : IConnPoolWrapper;

begin
    pServerName := '127.0.0.1';
    pDBName := 'Yktdata';
    pUser := 'sa';
    pPwd := '';
    pConnStr := 'Provider=SQLOLEDB.1;Persist Security Info=True;';
    pConnStr := pConnStr + 'Data Source=' + pServerName+'; Initial Catalog=' + pDBName;
    pConnStr := pConnStr + ';User ID='+ pUser +'; Password=' + pPwd;

    FPackege := LoadPackage('PackageConnePool.bpl'); //加载包

    theClass := GetClass('TConnectionPoolWrapper');  //通过字符串获得类定义
    if theClass = nil then
    begin
        ShowMessage( 'TConnectionPoolWrapper not load' );
        exit;
    end;
    thePlugin := theClass.Create;       //创建实例
    adoWarpper := TConnectionPoolWrapper(thePlugin);
   
    Supports( thePlugin, StringToGUID( '{E08BDEB7-BCA3-4F24-AE2D-A8745ACE8708}'
        ), IPlug );                     //转换成IPlugin接口
    try
        IPlug.InitConnectionPool('');
        IPlug.SetConnectionString(pConnStr);
        IPlug.SetMaxConnections(3);

    finally
      IPlug := nil;
    end;
end;


最后建立TestSuite单元。

function  MyTestConnPool: ITestSuite;
var
  aTestSuite: TTestSuite;
begin
  aTestSuite := TTestSuite.Create('ConnPool测试包');
  aTestSuite.AddTests(TTestCaseFirst);
  aTestSuite.AddTests(TTestCaseBpl);
  Result := aTestSuite;
end;

initialization
   RegisterTest('ConnPool测试包', MyTestConnPool);

经过测试,发现数据池连接参数,并发数,正确无误。

posted @ 2011-04-23 18:18  gxch  阅读(1168)  评论(0编辑  收藏  举报