Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要文件数据的单元测试类?_C#_Unit Testing_Mocking - Fatal编程技术网

C# 需要文件数据的单元测试类?

C# 需要文件数据的单元测试类?,c#,unit-testing,mocking,C#,Unit Testing,Mocking,我正在扩展我们的单元测试套件,我遇到了一个特定的类,我正试图找出如何模拟它。我有一个接受byte[]数组作为参数的方法。在一个完美的世界中,这个字节数组将始终是一个包含某种形式的PDF文件。然后它从该pdf中提取所有表单字段并返回它们 我如何可能模拟依赖于文件数据的逻辑?我唯一真正的想法是将pdf包含在项目中,并使用IO读取测试文件,或者尝试动态生成pdf表单,然后提取这些字段 以下是PDF提取器的代码: public class PdfFormExtractor : IDisposable {

我正在扩展我们的单元测试套件,我遇到了一个特定的类,我正试图找出如何模拟它。我有一个接受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
}

您可以使用Microsoft.Fakes为*.dll生成假程序集。利用赝品,我们可以改变任何属性、方法的结果

我伪造了Sqlconnection类,该类通常为模拟而硬化

  • 右键单击程序集(在我的示例中为System.Data)
  • 创建伪造程序集
  • 它创建
    垫片
    短桩
  • 我们需要使用(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
    }
    
    }

  • 希望这有帮助

    使用资源文件

    在VisualStudio中,只需在测试项目中创建一个资源文件,以包含要在测试中使用的所有文件。 打开resx,您将看到通常的字符串列表。但您不限于字符串:您可以在左上角的下拉列表中选择“文件”,然后将文件拖放到resx文件中。
    在执行此操作时,请注意粘贴的文件属性:您可以选择将文件解释为二进制文件(在您的用例中,字节[]是公开的)或文本(使用编码,它公开一个字符串)

    然后,在测试中,您可以只引用强类型资源对象和带有测试文件内容的强类型字节[]

    在测试复杂场景时,这种策略有很多应用程序,特别是与足够智能的序列化器/反序列化器(如Json.NET)配合使用时


    您可以将任何复杂的数据结构序列化为Json,然后在测试中将其作为字符串引用(由资源文件的类直接公开),使用简单的
    JsonConvert.DeserializeObject对其进行反序列化,并直接在业务逻辑上运行测试。

    可能的重复我不太确定解决方案是否需要文件系统依赖项,因为我可以插入字节[]包含文件数据,而不是从磁盘获取数据。如果您知道这是一种可能性@JDDavis,我不知道您为什么要问这个问题?@mjwills我希望除了生成pdf之外还有一些简单的方法。我不想在我的应用程序的这一部分中引入对Pdf库的引用(但这是有可能的)。对于要编写单元测试的方法,您是否有任何伪代码?