用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);
经过测试,发现数据池连接参数,并发数,正确无误。