您的位置:首页 > 其它

测试驱动开发例子学习-Using TDD with ADO.NET

2007-10-25 21:25 756 查看
来源:博客园使用智能客户端http://www.cnblogs.com/jasonw/archive/2004/10/10/50659.html
1.连接字符串的测试驱动范例:
[align=left]DataBase-SQLServer2000:
1.ConnectingtotheDatabase
2.XML应用程序的配置文件:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<appSettings>
<addkey="Catalog.Connection"
value="server=(local);database=catalog;Trusted_Connection=true"/>
</appSettings>
</configuration>

[/align]
[align=left]usingSystem;[/align]
[align=left]usingSystem.Data;[/align]
[align=left]usingSystem.Data.SqlClient;[/align]
[align=left]usingNUnit.Framework;[/align]
[align=left][/align]
[align=left][TestFixture][/align]
[align=left]publicclassSqlConnectionFixture[/align]
[align=left]{[/align]
[align=left][Test][/align]
[align=left]publicvoidConnectionIsOpen()[/align]
[align=left]{
//使用配置文件定义连接字符串
//stringconnectionString=[/align]
[align=left]//ConfigurationSettings.AppSettings.Get("Catalog.Connection");[/align]
[align=left]//Assert.IsNotNull(connectionString);[/align]
[align=left][/align]
[align=left]SqlConnectionconnection=[/align]
[align=left]newSqlConnection([/align]
[align=left]@"server=(local);database=catalog;Trusted_Connection=true");[/align]
[align=left]connection.Open();[/align]
[align=left]Assert.AreEqual(ConnectionState.Open,connection.State);[/align]
[align=left]connection.Close();[/align]
[align=left]}[/align]
[align=left]}

[/align]
2.连接字符串的测试驱动优化范例:
[align=left]
以上代码可以替换为:[/align]
[align=left][TestFixture][/align]
[align=left]publicclassSqlConnectionFixture[/align]
[align=left]{[/align]
[align=left]privatestringconnectionString;[/align]
[align=left][/align]
[align=left][SetUp][/align]
[align=left]publicvoidRetrieveConnectionString()[/align]
[align=left]{[/align]
[align=left]connectionString=[/align]
[align=left]ConfigurationSettings.AppSettings.Get("Catalog.Connection");[/align]
[align=left]}[/align]
[align=left][/align]
[align=left][Test][/align]
[align=left]publicvoidCanRetrieveConnectionString()[/align]
[align=left]{[/align]
[align=left]Assert.IsNotNull(connectionString);[/align]
[align=left]}[/align]
[align=left][/align]
[align=left][Test][/align]
[align=left]publicvoidConnectionIsOpen()[/align]
[align=left]{[/align]
[align=left]SqlConnectionconnection=[/align]
[align=left]newSqlConnection(connectionString);[/align]
[align=left]connection.Open();[/align]
[align=left]Assert.AreEqual(ConnectionState.Open,connection.State);[/align]
[align=left]connection.Close();[/align]
[align=left]}[/align]
[align=left]}

[/align]
3.ArtistGateway实现数据访问层的一个范例
对数据表artist的通用操作
usingSystem;

usingSystem.Data;

usingSystem.Data.SqlClient;


namespaceDataAccessLayer

{

publicclassArtistGateway

{

privateSqlDataAdapteradapter;

privateSqlConnectionconnection;

privateSqlCommandcommand;

privateSqlCommandBuilderbuilder;


publicArtistGateway(SqlConnectionconnection)

{

this.connection=connection;


command=newSqlCommand(

"selectid,namefromartistwhereid=@id",

connection);

command.Parameters.Add("@id",SqlDbType.BigInt);


adapter=newSqlDataAdapter(command);

builder=newSqlCommandBuilder(adapter);

}


publiclongInsert(

RecordingDataSetrecordingDataSet,stringartistName)

{

longartistId=

GetNextId(recordingDataSet.Artists.TableName);


RecordingDataSet.ArtistartistRow=

recordingDataSet.Artists.NewArtist();

artistRow.Id=artistId;

artistRow.Name=artistName;

recordingDataSet.Artists.AddArtist(artistRow);


adapter.Update(recordingDataSet,

recordingDataSet.Artists.TableName);


returnartistId;

}


publicRecordingDataSet.Artist

FindById(longartistId,RecordingDataSetrecordingDataSet)

{

command.Parameters["@id"].Value=artistId;

adapter.Fill(recordingDataSet,

recordingDataSet.Artists.TableName);

DataRow[]rows=recordingDataSet.Artists.Select(

String.Format("id={0}",artistId));


if(rows.Length<1)returnnull;

return(RecordingDataSet.Artist)rows[0];

}


publiclongGetNextId(stringtableName)

{

SqlTransactiontransaction=

connection.BeginTransaction(

IsolationLevel.Serializable,"GenerateId");


SqlCommandselectCommand=newSqlCommand(

"selectnextIdfromPKSequencewheretableName=@tableName",

connection,transaction);

selectCommand.Parameters.Add("@tableName",

SqlDbType.VarChar).Value=tableName;


longnextId=(long)selectCommand.ExecuteScalar();

SqlCommandupdateCommand=newSqlCommand(

"updatePKSequencesetnextId=@nextIdwheretableName=@tableName",

connection,transaction);

updateCommand.Parameters.Add("@tableName",

SqlDbType.VarChar).Value=tableName;

updateCommand.Parameters.Add("@nextId",

SqlDbType.BigInt).Value=nextId+1;

updateCommand.ExecuteNonQuery();

transaction.Commit();


returnnextId;

}

4.ArtistFixture.cs数据访问层代理类的测试用例
usingSystem;

usingSystem.Configuration;

usingSystem.Data;

usingSystem.Data.SqlClient;

usingDataAccessLayer;

usingNUnit.Framework;


[TestFixture]

publicclassArtistFixture

{

[Test]

publicvoidRetrieveArtistFromDatabase()

{

stringartistName="Artist";


SqlConnectionconnection=

newSqlConnection(

ConfigurationSettings.AppSettings.Get(

"Catalog.Connection"));

connection.Open();


ArtistGatewaygateway=newArtistGateway(connection);

longartistId=

gateway.Insert(newRecordingDataSet(),artistName);


RecordingDataSetloadedFromDB=newRecordingDataSet();

RecordingDataSet.ArtistloadedArtist=

gateway.FindById(artistId,loadedFromDB);


Assert.AreEqual(artistId,loadedArtist.Id);

Assert.AreEqual(artistName,loadedArtist.Name);


gateway.Delete(loadedFromDB,artistId);//删除功能的驱动

connection.Close();

}

}

5.删除驱动所形成的实现代码:
[align=left]publicvoidDelete(RecordingDataSetrecordingDataSet,longartistId)[/align]
[align=left]{[/align]
[align=left]RecordingDataSet.ArtistloadedArtist=[/align]
[align=left]FindById(artistId,recordingDataSet);[/align]
[align=left][/align]
[align=left]loadedArtist.Delete();[/align]
[align=left][/align]
[align=left]adapter.Update(recordingDataSet,[/align]
[align=left]recordingDataSet.Artists.TableName);[/align]
}

6.有了完整的测试用例,以及实现的代码,可以进行重构:
//首先优化测试的代码:
[TestFixture]

publicclassArtistFixture

{

privatestaticreadonlystringartistName="Artist";

privateSqlConnectionconnection;

privateArtistGatewaygateway;

privateRecordingDataSetrecordingDataSet;

privatelongartistId;


[SetUp]

publicvoidSetUp()

{

connection=newSqlConnection(

ConfigurationSettings.AppSettings.Get(

"Catalog.Connection"));

connection.Open();


recordingDataSet=newRecordingDataSet();

gateway=newArtistGateway(connection);


artistId=gateway.Insert(recordingDataSet,artistName);

}


[TearDown]

publicvoidTearDown()

{

gateway.Delete(recordingDataSet,artistId);

connection.Close();

}


[Test]

publicvoidRetrieveArtistFromDatabase()

{

RecordingDataSetloadedFromDB=newRecordingDataSet();

RecordingDataSet.ArtistloadedArtist=

gateway.FindById(artistId,loadedFromDB);


Assert.AreEqual(artistId,loadedArtist.Id);

Assert.AreEqual(artistName,loadedArtist.Name);

}


[Test]

publicvoidDeleteArtistFromDatabase()

{

RecordingDataSetemptyDataSet=newRecordingDataSet();

longdeletedArtistId=gateway.Insert(emptyDataSet,"DeletedArtist");

gateway.Delete(emptyDataSet,deletedArtistId);


RecordingDataSet.ArtistdeleletedArtist=

gateway.FindById(deletedArtistId,emptyDataSet);

Assert.IsNull(deleletedArtist);

}

}


7.在重构的基础上加入更新方法:.
[Test]

publicvoidUpdateArtistInDatabase()

{

RecordingDataSet.Artistartist=recordingDataSet.Artists[0];

artist.Name="ModifiedName";

gateway.Update(recordingDataSet);


RecordingDataSetupdatedDataSet=newRecordingDataSet();

RecordingDataSet.ArtistupdatedArtist=

gateway.FindById(artistId,updatedDataSet);

Assert.AreEqual("ModifiedName",updatedArtist.Name);

}

//ThefollowingistheimplementationofUpdate:
publicvoidUpdate(RecordingDataSetrecordingDataSet)

{

adapter.Update(recordingDataSet,

recordingDataSet.Artists.TableName);

}


8.GenreGateway另一个测试驱动的例子(类似于artists)
[TestFixture]

publicclassGenreFixture

{

privatestaticreadonlystringgenreName="Rock";

privateSqlConnectionconnection;

privateGenreGatewaygateway;

privateRecordingDataSetrecordingDataSet;

privatelonggenreId;


[SetUp]

publicvoidSetUp()

{

connection=newSqlConnection(

ConfigurationSettings.AppSettings.Get(

"Catalog.Connection"));

connection.Open();


recordingDataSet=newRecordingDataSet();

gateway=newGenreGateway(connection);


genreId=gateway.Insert(recordingDataSet,genreName);

}


[TearDown]

publicvoidTearDown()

{

gateway.Delete(recordingDataSet,genreId);

connection.Close();

}


[Test]

publicvoidRetrieveGenreFromDatabase()

{

RecordingDataSetloadedFromDB=newRecordingDataSet();

RecordingDataSet.GenreloadedGenre=

gateway.FindById(genreId,loadedFromDB);


Assert.AreEqual(genreId,loadedGenre.Id);

Assert.AreEqual(genreName,loadedGenre.Name);

}

}

9.实现部分GenreGateway:
publicclassGenreGateway

{

privateSqlDataAdapteradapter;

privateSqlConnectionconnection;

privateSqlCommandcommand;

privateSqlCommandBuilderbuilder;


publicGenreGateway(SqlConnectionconnection)

{

this.connection=connection;


command=newSqlCommand(

"selectid,namefromGenrewhereid=@id",

connection);

command.Parameters.Add("@id",SqlDbType.BigInt);


adapter=newSqlDataAdapter(command);

builder=newSqlCommandBuilder(adapter);

}


publiclongInsert(RecordingDataSetrecordingDataSet,

stringgenreName)

{

longgenreId=GetNextId(recordingDataSet.Genres.TableName);


RecordingDataSet.GenregenreRow=

recordingDataSet.Genres.NewGenre();

genreRow.Id=genreId;

genreRow.Name=genreName;

recordingDataSet.Genres.AddGenre(genreRow);


adapter.Update(recordingDataSet,

recordingDataSet.Genres.TableName);


returngenreId;

}


publicRecordingDataSet.Genre

FindById(longgenreId,RecordingDataSetrecordingDataSet)

{

command.Parameters["@id"].Value=genreId;

adapter.Fill(recordingDataSet,

recordingDataSet.Genres.TableName);

DataRow[]rows=recordingDataSet.Genres.Select(

String.Format("id={0}",genreId));


if(rows.Length<1)returnnull;

return(RecordingDataSet.Genre)rows[0];

}


publicvoidDelete(RecordingDataSetrecordingDataSet,

longgenreId)

{

RecordingDataSet.GenreloadedGenre=

FindById(genreId,recordingDataSet);

loadedGenre.Delete();

adapter.Update(recordingDataSet,

recordingDataSet.Genres.TableName);

}


publiclongGetNextId(stringtableName)

{/*sameasinArtistGateway*/}

}


10.获取下一个ID
[TestFixture]

publicclassIdGeneratorFixture

{

privateSqlConnectionconnection;


[SetUp]

publicvoidOpenConnection()

{

connection=newSqlConnection(

ConfigurationSettings.AppSettings.Get(

"Catalog.Connection"));

connection.Open();

}


[Test]

publicvoidGetNextIdIncrement()

{

SqlCommandsqlCommand=newSqlCommand(

"selectnextIdfromPKSequencewheretableName=@tableName",

connection);


sqlCommand.Parameters.Add(

"@tableName",SqlDbType.VarChar).Value="Artist";


longnextId=(long)sqlCommand.ExecuteScalar();

longnextIdFromGenerator=

IdGenerator.GetNextId("Artist",connection);

Assert.AreEqual(nextId,nextIdFromGenerator);

nextId=(long)sqlCommand.ExecuteScalar();

Assert.AreEqual(nextId,nextIdFromGenerator+1);

}


[TearDown]

publicvoidCloseConnection()

{

connection.Close();

}

}

//实现部分
publicclassIdGenerator

{

publicstaticlongGetNextId(stringtableName,

SqlConnectionconnection)

{

SqlTransactiontransaction=connection.BeginTransaction(

IsolationLevel.Serializable,"GenerateId");


SqlCommandselectCommand=newSqlCommand(

"selectnextIdfromPKSequencewheretableName=@tableName",

connection,transaction);

selectCommand.Parameters.Add("@tableName",

SqlDbType.VarChar).Value=tableName;


longnextId=(long)selectCommand.ExecuteScalar();

SqlCommandupdateCommand=newSqlCommand(

"updatePKSequencesetnextId=@nextIdwheretableName=@tableName",

connection,transaction);

updateCommand.Parameters.Add("@tableName",SqlDbType.VarChar).Value=tableName;

updateCommand.Parameters.Add("@nextId",SqlDbType.BigInt).Value=nextId+1;

updateCommand.ExecuteNonQuery();

transaction.Commit();

returnnextId;

}

}

11.IdGeneratorFixture.cs优化过得实现:
usingSystem;

usingSystem.Configuration;

usingSystem.Data;

usingSystem.Data.SqlClient;

usingNUnit.Framework;

usingDataAccessLayer;


[TestFixture]

publicclassIdGeneratorFixture:ConnectionFixture

{

[Test]

publicvoidGetNextIdIncrement()

{

SqlCommandsqlCommand=

newSqlCommand(

"selectnextIdfromPKSequencewheretableName=@tableName",

Connection);

sqlCommand.Parameters.Add("@tableName",SqlDbType.VarChar).Value="Artist";


longnextId=(long)sqlCommand.ExecuteScalar();

longnextIdFromGenerator=IdGenerator.GetNextId("Artist",Connection);

Assert.AreEqual(nextId,nextIdFromGenerator);

nextId=(long)sqlCommand.ExecuteScalar();

Assert.AreEqual(nextId,nextIdFromGenerator+1);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: