kdm*_*ray 63 database testing integration-testing unit-testing data-access-layer
我已经接近一个新项目的开始了(喘气!)我第一次尝试将单元测试包含在我的项目中.
我自己设计一些单元测试时遇到了麻烦.我有一些方法很容易测试(传入两个值并检查预期的输出).我有代码的其他部分正在做更复杂的事情,比如对数据库运行查询,我不知道如何测试它们.
public DataTable ExecuteQuery(SqlConnection ActiveConnection, string Query, SqlParameterCollection Parameters)
{
DataTable resultSet = new DataTable();
SqlCommand queryCommand = new SqlCommand();
try
{
queryCommand.Connection = ActiveConnection;
queryCommand.CommandText = Query;
if (Parameters != null)
{
foreach (SqlParameter param in Parameters)
{
queryCommand.Parameters.Add(param);
}
}
SqlDataAdapter queryDA = new SqlDataAdapter(queryCommand);
queryDA.Fill(resultSet);
}
catch (Exception ex)
{
//TODO: Improve error handling
Console.WriteLine(ex.Message);
}
return resultSet;
}
Run Code Online (Sandbox Code Playgroud)
此方法基本上包含从数据库中提取一些数据所需的所有必要部分,并返回DataTable对象中的数据.
第一个问题可能是最复杂的问题:在这样的情况下我应该测试什么?
一旦解决了问题,是否要模拟数据库组件或尝试对实际数据库进行测试.
tpd*_*pdi 47
你在测试什么?
我的头顶有三种可能性:
答:您正在测试DAO(数据访问对象)类,确保它正确地编组传递给数据库的值/参数,并正确地编组/转换/打包数据库中的结果.
在这种情况下,您根本不需要连接到数据库; 你只需要一个单元测试,用一个模拟替换数据库(或中间层,例如,JDBC,(N)Hibernate,iBatis).
B.您正在测试(生成的)SQL的语法正确性.
在这种情况下,由于SQL方言不同,您希望针对正确版本的RDBMS运行(可能生成的)SQL,而不是尝试模拟RDBMS的所有怪癖(以便任何更改功能的RDBMS升级都被捕获你的测试).
C.您正在测试SQL 的语义正确性,即对于给定的基线数据集,您的操作(访问/选择和突变/插入和更新)会生成预期的新数据集.
为此,您希望使用类似dbunit(允许您设置基线并将结果集与预期结果集进行比较),或者可能使用我在此处概述的技术完全在数据库中进行测试:最佳方式测试SQL查询.
Mus*_*sis 28
这就是为什么(恕我直言)单元测试有时会给开发人员带来错误的安全感.根据我与数据库通信的应用程序的经验,错误通常是数据处于意外状态(异常或缺失值等)的结果.如果您经常在单元测试中模拟数据访问,那么当您的代码实际上仍然容易受到此类错误的影响时,您会认为代码运行良好.
我认为你最好的方法是有一个方便的测试数据库,充满了大量糟糕的数据,并针对它运行数据库组件测试.一直记住,你的用户将比你搞砸数据要好得多.
Jör*_*tag 10
单元测试的重点是单独测试一个单元(duh).数据库调用的重点是与另一个单元(数据库)集成.Ergo:单元测试数据库调用没有意义.
但是,您应该集成测试数据库调用(如果需要,您可以使用与单元测试相同的工具).
为了爱上帝,不要对已经填充的实时数据库进行测试.但你知道的.
通常,您已经知道每个查询将检索哪种数据,无论您是在验证用户,查找电话簿/组织图表条目,还是其他任何内容.你知道哪些领域你有兴趣,你知道他们存在哪些制约因素(如UNIQUE,NOT NULL等).您是对与数据库交互的代码进行单元测试,而不是数据库本身,因此请考虑如何测试这些函数.如果字段可能存在NULL,则应该进行测试以确保代码NULL正确处理值.如果您的某个字段是字符串(CHAR,, VARCHAR和TEXT,c),请进行测试以确保正确处理转义字符.
假设用户将尝试将任何*放入数据库,并相应地生成测试用例.你会想要使用模拟对象.
*包括不良,恶意或无效的输入.