我正在扩展我们的单元测试套件,并且遇到了一个特定的类,我试图弄清楚如何进行模拟。我有一个方法可以接受byte []数组作为参数。在理想情况下,此字节数组将始终是包含某种形式的PDF文件。然后,它从该pdf中提取所有表单字段并返回它们。
如何潜在地模拟依赖于文件数据的逻辑?我唯一真正的想法是将pdf包含在项目中,并使用IO读取测试文件,或者尝试动态生成pdf表单,然后提取这些字段。
这是PDF提取器的代码:
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
}
答案 0 :(得分:1)
使用资源文件。
在Visual Studio中,只需在测试项目中创建一个资源文件,以包含要在测试中使用的所有文件。
打开resx,您将看到通常的字符串列表。但您不仅限于字符串:您可以在左上角的下拉菜单中选择“文件”,然后将文件拖放到resx文件中。
在执行此操作时,请注意粘贴的文件属性:您可以选择将文件解释为二进制文件(如用例所示,显示为byte [])或文本(编码格式,显示为字符串)。
然后,在您的测试中,您可以仅使用测试文件的内容引用强类型的Resource对象和强类型的byte []。
在测试复杂场景时,尤其是与足够智能的序列化器/反序列化器(如Json.NET)配对使用时,此策略有很多应用。
您可以将任何复杂的数据结构序列化为Json,然后在测试中将其引用为字符串(直接由Resource文件的类公开),使用简单的JsonConvert.DeserializeObject
反序列化并在业务逻辑上运行测试直接。
答案 1 :(得分:0)
您可以使用Microsoft.Fakes为* .dll生成假程序集。借助Fakes,我们可以弯曲任何属性,方法等的结果。
我伪造了Sqlconnection类,通常会对其进行模拟强化。
shims
和stubs
我们需要使用(ShimsContext.Create())添加范围。示波器中的所有内容都将按照您的建议进行操作。
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
}
}
希望这会有所帮助!