在我们的测试应用程序中,我们首先从数据库获得我们的结果集,然后将它们转化成内存DataTable对象,从而为比较做准备。 TestDataTable类的构造函数接受一个数据库连接字符串和一个select查询。你还可以使用SetInputParameter函数设置输入参数。这个类的Table属性返回一个DataTable,它包含这个select查询的结果集。
class TestDataTable { private readonly SqlCommand _command; public TestDataTable(String connstr, String selectQuery, CommandType commandType) { SqlConnection conn = new SqlConnection(connstr); _command = new SqlCommand(selectQuery, conn); _command.CommandType = commandType; } public void SetInputParameter(string parameterName, object parameterValue) { if (_command.Parameters.Contains(parameterName)) _command.Parameters[parameterName] = new SqlParameter(parameterName, parameterValue); else _command.Parameters.AddWithValue(parameterName, parameterValue); } public DataTable Table { get { DataTable _dataTable = new DataTable(); SqlDataAdapter da = new SqlDataAdapter(_command); da.Fill(_dataTable); da.Dispose(); return _dataTable; } } } |
我们还需要一个类使用LINQ来比较两个DataTable对象,并将两个结果集间的差异写入在一个变量logFilePath中指定的文件中。ResultSetComparer类做这个工作。
class ResultSetComparer { private static StreamWriter sw = null; private static void InitWriter(String filePath) { sw = new StreamWriter(filePath, true); } private static void Write(DataTable dt) { int i = 0; try { sw.WriteLine(System.DateTime.Now.ToString()); sw.WriteLine(); for (i = 0; i < dt.Columns.Count - 1; i++) { sw.Write(dt.Columns[i].ColumnName + " | "); } sw.Write(dt.Columns[i].ColumnName); sw.WriteLine(); foreach (DataRow row in dt.Rows) { object[] array = row.ItemArray; for (i = 0; i < array.Length - 1; i++) { sw.Write(array[i].ToString() + " | "); } sw.Write(array[i].ToString()); sw.WriteLine(); } sw.Close(); } catch (Exception ex) { Console.WriteLine("Invalid Operation when writing data table: \n" + ex.ToString()); } } public static bool AreIdenticalResultSets(DataTable dt1, DataTable dt2, String logFilePath) { var v1 = dt1.AsEnumerable(); var v2 = dt2.AsEnumerable(); var diff1 = v1.Except(v2, DataRowComparer.Default); var diff2 = v2.Except(v1, DataRowComparer.Default); if (diff1.Any()) { InitWriter(logFilePath); sw.WriteLine("Rows in the first table, but not in the second table:"); DataTable diffTbl1 = diff1.CopyToDataTable(); Write(diffTbl1); sw.Close(); } if (diff2.Any()) { InitWriter(logFilePath); sw.WriteLine("Rows in the second table, but not in the first table:"); DataTable diffTbl2 = diff2.CopyToDataTable(); Write(diffTbl2); sw.Close(); } return !(diff1.Any() || diff2.Any()); } } |
现在我们准备好开发我们的测试用例了。我们将使用NUnit框架中的下面这些组件。