C# 需要文件数据的单元测试类?
我正在扩展我们的单元测试套件,我遇到了一个特定的类,我正试图找出如何模拟它。我有一个接受byte[]数组作为参数的方法。在一个完美的世界中,这个字节数组将始终是一个包含某种形式的PDF文件。然后它从该pdf中提取所有表单字段并返回它们 我如何可能模拟依赖于文件数据的逻辑?我唯一真正的想法是将pdf包含在项目中,并使用IO读取测试文件,或者尝试动态生成pdf表单,然后提取这些字段 以下是PDF提取器的代码:C# 需要文件数据的单元测试类?,c#,unit-testing,mocking,C#,Unit Testing,Mocking,我正在扩展我们的单元测试套件,我遇到了一个特定的类,我正试图找出如何模拟它。我有一个接受byte[]数组作为参数的方法。在一个完美的世界中,这个字节数组将始终是一个包含某种形式的PDF文件。然后它从该pdf中提取所有表单字段并返回它们 我如何可能模拟依赖于文件数据的逻辑?我唯一真正的想法是将pdf包含在项目中,并使用IO读取测试文件,或者尝试动态生成pdf表单,然后提取这些字段 以下是PDF提取器的代码: public class PdfFormExtractor : IDisposable {
public class PdfFormExtractor : IDisposable
{
private readonly PdfReader _pdfReader;
private readonly MemoryStream _newPdf;
private readonly PdfStamper _pdfStamper;
public PdfFormExtractor(byte[] pdf)
{
_pdfReader = new PdfReader(pdf);
_newPdf = new MemoryStream();
_pdfStamper = new PdfStamper(_pdfReader, _newPdf);
}
public FormDto ExtractForm()
{
var pdfFormFields = _pdfStamper.AcroFields;
var form = new FormDto()
{
Fields = pdfFormFields.Fields.Select(n => new FormFieldDto
{
Name = n.Key,
Label = n.Key
}).ToList()
};
return form;
}
#region IDisposable Support
// disposable implementation
#endregion
}
您可以使用Microsoft.Fakes为*.dll生成假程序集。利用赝品,我们可以改变任何属性、方法的结果 我伪造了Sqlconnection类,该类通常为模拟而硬化
垫片
和短桩
public void ExtractFormTest()
{
using (ShimsContext.Create())
{
#region FakeIt
System.Data.SqlClient.Fakes.ShimSqlConnection.AllInstances.Open = (SqlConnection sqlConnection) =>
{
Console.WriteLine("Opened a session with Virtual Sql Server");
};
System.Data.SqlClient.Fakes.ShimSqlConnection.AllInstances.Close = (SqlConnection sqlConnection) =>
{
Console.WriteLine("Closed the session with Virtual Sql Server");
};
System.Data.SqlClient.Fakes.ShimSqlCommand.AllInstances.ExecuteNonQuery = (SqlCommand sqlCommand) =>
{
if (sqlCommand.CommandText.ToLower().Contains("truncate table"))
{
Console.WriteLine("Ran " + sqlCommand.CommandText + " at Virtual Sql Server");
return 1;
}
return 0;
};
System.Data.SqlClient.Fakes.ShimSqlBulkCopy.AllInstances.WriteToServerDataTable = (SqlBulkCopy sqlBulkCopy, DataTable datatable) =>
{
Console.WriteLine("Written #" + datatable.Rows.Count + " records to Virtual Sql Server");
};
System.Data.Common.Fakes.ShimDbDataAdapter.AllInstances.FillDataSet = (DbDataAdapter dbDataAdapter, DataSet dataSet) =>
{
var _dataSet = new DataSet();
var _dataTable = DataTableHelper.LoadFlatfileIntoDataTable(Path.Combine(dailyEmailFlatfilesDirectory, "Flatfile.txt"), flatfileDelimiter, flatfileDataTableFields, regexPatternMdmValidEmail, traceWriter);
if (dbDataAdapter.SelectCommand.CommandText.Equals(mdmSqlStorProcForSpFlatfileData))
{
while (_dataTable.Rows.Count > 1000)
_dataTable.Rows.RemoveAt(0);
}
else if (dbDataAdapter.SelectCommand.CommandText.Equals(mdmSqlStorProcForStFlatfileData))
{
while (_dataTable.Rows.Count > 72)
_dataTable.Rows.RemoveAt(0);
}
dataSet.Tables.Add(_dataTable);
dataSet = _dataSet;
return 1;
};
#endregion
#region Act
FormDto formDto = ExtractForm();
#endregion
#region Assert
// Upto the scope of your method and acceptance criteria
#endregion
}
}在执行此操作时,请注意粘贴的文件属性:您可以选择将文件解释为二进制文件(在您的用例中,字节[]是公开的)或文本(使用编码,它公开一个字符串) 然后,在测试中,您可以只引用强类型资源对象和带有测试文件内容的强类型字节[] 在测试复杂场景时,这种策略有很多应用程序,特别是与足够智能的序列化器/反序列化器(如Json.NET)配合使用时
您可以将任何复杂的数据结构序列化为Json,然后在测试中将其作为字符串引用(由资源文件的类直接公开),使用简单的
JsonConvert.DeserializeObject对其进行反序列化,并直接在业务逻辑上运行测试。可能的重复我不太确定解决方案是否需要文件系统依赖项,因为我可以插入字节[]包含文件数据,而不是从磁盘获取数据。如果您知道这是一种可能性@JDDavis,我不知道您为什么要问这个问题?@mjwills我希望除了生成pdf之外还有一些简单的方法。我不想在我的应用程序的这一部分中引入对Pdf库的引用(但这是有可能的)。对于要编写单元测试的方法,您是否有任何伪代码?