C# 使用Moq对datatable导出服务进行单元测试
我有一个服务要导出为csv文件,该文件位于WPF应用程序的videmodel中:C# 使用Moq对datatable导出服务进行单元测试,c#,wpf,unit-testing,moq,C#,Wpf,Unit Testing,Moq,我有一个服务要导出为csv文件,该文件位于WPF应用程序的videmodel中: public void ExportToExcel() { DataTable tblFiltered = _currentTable.AsEnumerable() .Where(r => r.Field<string>("Type") == ExportGridGroup)
public void ExportToExcel()
{
DataTable tblFiltered = _currentTable.AsEnumerable()
.Where(r => r.Field<string>("Type") == ExportGridGroup)
.CopyToDataTable();
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = tblFiltered.Columns.Cast<DataColumn>().
Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in tblFiltered.Rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field => "\"" + field.ToString() + "\"");
sb.AppendLine(string.Join(",", fields));
}
String result = sb.ToString();
try
{
StreamWriter sw = new StreamWriter("export.csv");
sw.WriteLine(result);
sw.Close();
Process.Start("export.csv");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void ExportToExcel()
{
DataTable tblFiltered=\u currentTable.AsEnumerable()
其中(r=>r.Field(“Type”)==ExportGridGroup)
.CopyToDataTable();
StringBuilder sb=新的StringBuilder();
IEnumerable columnNames=tblFiltered.Columns.Cast()。
选择(column=>column.ColumnName);
sb.AppendLine(string.Join(“,”,columnNames));
foreach(tblFiltered.Rows中的数据行)
{
IEnumerable fields=row.ItemArray.Select(field=>“\”+field.ToString()+“\”);
sb.AppendLine(string.Join(“,”字段));
}
字符串结果=sb.ToString();
尝试
{
StreamWriter sw=新StreamWriter(“export.csv”);
软件写入线(结果);
sw.Close();
Process.Start(“export.csv”);
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}
基于此,我为它创建了一个测试方法,但还没有完成
[TestMethod()]
public void ExportToExcelTest()
{
//Step 1: Creating a mock table with columns
DataTable testtable = new DataTable();
DataRow mydatarow;
mydatarow = testtable.NewRow();
//Step 2: Adding the row
mydatarow["ColumnA"] = "12345";
mydatarow["ColumnB"] = "test";
testtable.Rows.Add(mydatarow);
StringBuilder sb = new StringBuilder();
IEnumerable<string> columnNames = testtable.Columns.Cast<DataColumn>().
Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in testtable.Rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field => "\"" + field.ToString() + "\"");
sb.AppendLine(string.Join(",", fields));
}
String result = sb.ToString();
StreamWriter sw = new StreamWriter("export.csv");
sw.WriteLine(result);
sw.Close();
Process.Start("export.csv");
Assert.Fail();
}
[TestMethod()]
公共无效ExportToExcelTest()
{
//步骤1:创建包含列的模拟表
DataTable testtable=新DataTable();
数据行mydatarow;
mydatarow=testtable.NewRow();
//步骤2:添加行
mydatarow[“ColumnA”]=“12345”;
mydatarow[“ColumnB”]=“测试”;
testtable.Rows.Add(mydatarow);
StringBuilder sb=新的StringBuilder();
IEnumerable columnNames=testtable.Columns.Cast()。
选择(column=>column.ColumnName);
sb.AppendLine(string.Join(“,”,columnNames));
foreach(testtable.Rows中的DataRow行)
{
IEnumerable fields=row.ItemArray.Select(field=>“\”+field.ToString()+“\”);
sb.AppendLine(string.Join(“,”字段));
}
字符串结果=sb.ToString();
StreamWriter sw=新StreamWriter(“export.csv”);
软件写入线(结果);
sw.Close();
Process.Start(“export.csv”);
Assert.Fail();
}
我有点困惑,因为在测试方法中,我几乎在项目中编写了完全相同的代码。。。。。
关于如何编写此单元测试以及有关WPF/C#单元测试的任何详细参考,我可以从Moq开始提供一些建议吗?考虑将
try
块中的代码提取到另一个服务中
public interface ICsvWriter
{
void WriteOutput(string text);
}
并将其作为依赖项传递给导出服务的构造函数
public Service(ICsvWriter csvWriter)
{
this.csvWriter = csvWriter;
}
然后,您可以编写这样的测试来验证它是否实际输出了您期望的内容
[TestMethod]
public void TestMethod1()
{
var csvWriter= new Mock<ICsvWriter>();
var service = new Service(csvWriter.Object);
string exportedText = string.Empty;
// set up your mock so that whatatever string you pass in
// gets passed to your exportedText variable.
csvWriter.Setup(s => s.WriteOutput(It.IsAny<string>())).Callback<string>(s => exportedText = s);
var testtable = new DataTable();
// .... add test data
// set the table on the view model
service.SetData(testtable);
// call the export method.
service.ExportToExcel();
// check that the result matches your expectation
Assert.AreEqual("the text you expect to be written", exportedText);
}
更新
您还可以通过将DataTable
作为参数传入,来提高导出方法的可测试性。然后,您可以在没有用于设置数据的公共属性的情况下对其进行测试
public void ExportToExcel(DataTable currentTable)
{
DataTable tblFiltered = currentTable.AsEnumerable()
.Where(r => r.Field<string>("Type") == ExportGridGroup)
.CopyToDataTable();
// ...
}
考虑将
try
块中的代码提取到其他服务
public interface ICsvWriter
{
void WriteOutput(string text);
}
并将其作为依赖项传递给导出服务的构造函数
public Service(ICsvWriter csvWriter)
{
this.csvWriter = csvWriter;
}
然后,您可以编写这样的测试来验证它是否实际输出了您期望的内容
[TestMethod]
public void TestMethod1()
{
var csvWriter= new Mock<ICsvWriter>();
var service = new Service(csvWriter.Object);
string exportedText = string.Empty;
// set up your mock so that whatatever string you pass in
// gets passed to your exportedText variable.
csvWriter.Setup(s => s.WriteOutput(It.IsAny<string>())).Callback<string>(s => exportedText = s);
var testtable = new DataTable();
// .... add test data
// set the table on the view model
service.SetData(testtable);
// call the export method.
service.ExportToExcel();
// check that the result matches your expectation
Assert.AreEqual("the text you expect to be written", exportedText);
}
更新
您还可以通过将DataTable
作为参数传入,来提高导出方法的可测试性。然后,您可以在没有用于设置数据的公共属性的情况下对其进行测试
public void ExportToExcel(DataTable currentTable)
{
DataTable tblFiltered = currentTable.AsEnumerable()
.Where(r => r.Field<string>("Type") == ExportGridGroup)
.CopyToDataTable();
// ...
}
在测试的方法中有很多紧密耦合,我看不到在该方法中有效使用Moq的机会。考虑重构测试方法,依赖于服务抽象,使其在隔离中更可测试。单元测试应该执行一种方法并断言结果。因此,您应该调用
ExportToExcel
,而不是重新创建逻辑。然而,@Nikosi说了什么。这段代码实际上是不可测试的。在被测试的方法中有很多紧密耦合,我看不到有多少机会在该方法中有效地使用Moq。考虑重构测试方法,依赖于服务抽象,使其在隔离中更可测试。单元测试应该执行一种方法并断言结果。因此,您应该调用ExportToExcel
,而不是重新创建逻辑。然而,@Nikosi说了什么。这段代码实际上是不可测试的。