Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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# Excel中的单元测试数组_C#_.net_Unit Testing_Xunit.net - Fatal编程技术网

C# Excel中的单元测试数组

C# Excel中的单元测试数组,c#,.net,unit-testing,xunit.net,C#,.net,Unit Testing,Xunit.net,我想从Excel电子表格中的数据传递一个数组。注意,我不想对每一行运行一个测试,而是对整个列表运行一个测试 例如,类似以下内容: [Theory] [ExcelData("test.xls", "select * from [Sheet1$A1:A7]")] public void TestMyAverage(double[] values) { double desiredResult = values.Average(); Assert.True(MyAverage(desi

我想从Excel电子表格中的数据传递一个数组。注意,我不想对每一行运行一个测试,而是对整个列表运行一个测试

例如,类似以下内容:

[Theory]
[ExcelData("test.xls", "select * from [Sheet1$A1:A7]")]
public void TestMyAverage(double[] values)
{
    double desiredResult = values.Average();
    Assert.True(MyAverage(desiredResult));
}

但是,该特定代码无法工作,因为它试图将每一行(
double
)转换为
double[]
,从而导致错误。

我修改了
ExcelDataAttribute
。它还没有经过彻底的测试,但似乎有效

有两个新的可选参数:

  • 数据包含标题(与此问题无关)
  • 以数组形式返回数据
  • 用法示例:

    [Theory]
    [ExcelArrayData("test.xls", "select * from [Sheet1$A1:B7]", false, true)]
    public void TestMethod(int[] values, int[] values2)
    
    源代码:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.OleDb;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using Xunit.Sdk;
    
    namespace UnitTestCalculationStandards
    {
      [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
      public sealed class ExcelArrayDataAttribute : DataAttribute
      {
        string connectionTemplate =
            "Provider=Microsoft.ACE.OLEDB.12.0; Data Source={0}; Extended Properties='Excel 12.0;HDR=YES;IMEX=1;';";
        public ExcelArrayDataAttribute(string fileName, string queryString, bool hasHeader = true, bool returnAsArray = false)
        {
         // System.Diagnostics.Debugger.Launch();
          if (!hasHeader)
          {
            connectionTemplate = connectionTemplate.Replace("HDR=YES", "HDR=NO");
          }
          FileName = fileName;
          QueryString = queryString;
          ReturnAsArray = returnAsArray;
        }
        public string FileName { get; private set; }
        public string QueryString { get; private set; }
        private bool ReturnAsArray;
        public override IEnumerable<object[]> GetData(MethodInfo testMethod)
        {
          if (testMethod == null)
            throw new ArgumentNullException("testMethod");
    
          ParameterInfo[] pars = testMethod.GetParameters();
    
          if (ReturnAsArray)
          {
            return DataSourceAsEnumerable(FileName, QueryString, pars.Select(par => GetEnumerableType(par.ParameterType)).ToArray());
          }
          else
          {
            return DataSource(FileName, QueryString, pars.Select(par => par.ParameterType).ToArray());
          }
        }
        static Type GetEnumerableType(Type type)
        {
          foreach (Type intType in type.GetInterfaces())
          {
            if (intType.IsGenericType
                && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            {
              return intType.GetGenericArguments()[0];
            }
          }
          return null;
        }
        IEnumerable<object[]> DataSourceAsEnumerable(string fileName, string selectString, Type[] parameterTypes)
        {
          string connectionString = string.Format(connectionTemplate, GetFullFilename(fileName));
          IDataAdapter adapter = new OleDbDataAdapter(selectString, connectionString);
          DataSet dataSet = new DataSet();
    
          List<object[]> rows = new List<object[]>();
          try
          {
            adapter.Fill(dataSet);
    
            foreach (DataRow row in dataSet.Tables[0].Rows)
              rows.Add(ConvertParameters(row.ItemArray, parameterTypes));
          }
          finally
          {
            IDisposable disposable = adapter as IDisposable;
            disposable.Dispose();
          }
    
          object[] columns = new object[parameterTypes.Length];
          for (int i = 0; i < parameterTypes.Length; i++)
          {
            columns[i] = rows.Select(r => r[i]).ToList();
          }
          List<object[]> rv = new List<object[]>();
          rv.Add(columns.ToArray());
    
          return rv;
        }
        IEnumerable<object[]> DataSource(string fileName, string selectString, Type[] parameterTypes)
        {
          string connectionString = string.Format(connectionTemplate, GetFullFilename(fileName));
          IDataAdapter adapter = new OleDbDataAdapter(selectString, connectionString);
          DataSet dataSet = new DataSet();
    
          try
          {
            adapter.Fill(dataSet);
    
            foreach (DataRow row in dataSet.Tables[0].Rows)
              yield return ConvertParameters(row.ItemArray, parameterTypes);
          }
          finally
          {
            IDisposable disposable = adapter as IDisposable;
            disposable.Dispose();
          }
        }
        static string GetFullFilename(string filename)
        {
          string executable = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
          return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(executable), filename));
        }
    
        static object[] ConvertParameters(object[] values, Type[] parameterTypes)
        {
          object[] result = new object[values.Length];
    
          for (int idx = 0; idx < values.Length; idx++)
            result[idx] = ConvertParameter(values[idx], idx >= parameterTypes.Length ? null : parameterTypes[idx]);
    
          return result;
        }
    
        /// <summary>
        /// Converts a parameter to its destination parameter type, if necessary.
        /// </summary>
        /// <param name="parameter">The parameter value</param>
        /// <param name="parameterType">The destination parameter type (null if not known)</param>
        /// <returns>The converted parameter value</returns>
        static object ConvertParameter(object parameter, Type parameterType)
        {
          if ((parameter is double || parameter is float) &&
              (parameterType == typeof(int) || parameterType == typeof(int?)))
          {
            int intValue;
            string floatValueAsString = parameter.ToString();
    
            if (Int32.TryParse(floatValueAsString, out intValue))
              return intValue;
          }
    
          return parameter;
        }
    
    
      }
    
    }
    
    使用系统;
    使用System.Collections.Generic;
    使用系统数据;
    使用System.Data.OleDb;
    使用System.IO;
    使用System.Linq;
    运用系统反思;
    使用Xunit.Sdk;
    命名空间UnitTestCalculationStandards
    {
    [AttributeUsage(AttributeTargets.Method,AllowMultiple=false,Inherited=false)]
    公共密封类ExcelArrayDataAttribute:DataAttribute
    {
    字符串连接模板=
    “Provider=Microsoft.ACE.OLEDB.12.0;数据源={0};扩展属性='excel12.0;HDR=YES;IMEX=1;';”;
    公共ExcelArrayDataAttribute(字符串文件名、字符串查询字符串、bool HashReader=true、bool returnAsArray=false)
    {
    //System.Diagnostics.Debugger.Launch();
    if(!hasHeader)
    {
    connectionTemplate=connectionTemplate.Replace(“HDR=YES”,“HDR=NO”);
    }
    FileName=文件名;
    QueryString=QueryString;
    ReturnAsArray=ReturnAsArray;
    }
    公共字符串文件名{get;private set;}
    公共字符串查询字符串{get;private set;}
    私人布尔返回阵列;
    公共重写IEnumerable GetData(MethodInfo testMethod)
    {
    if(testMethod==null)
    抛出新ArgumentNullException(“testMethod”);
    ParameterInfo[]pars=testMethod.GetParameters();
    如果(返回阵列)
    {
    返回DataSourceAnumerable(文件名、QueryString、pars.Select(par=>GetEnumerableType(par.ParameterType)).ToArray();
    }
    其他的
    {
    返回数据源(文件名、查询字符串、PARS。选择(PAL= > PAR。ParameterType)。toRayay.());
    }
    }
    静态类型GetEnumerableType(类型类型)
    {
    foreach(Type.GetInterfaces()中的intType类型)
    {
    如果(intType.IsGenericType
    &&intType.GetGenericTypeDefinition()==typeof(IEnumerable))
    {
    返回intType.GetGenericArguments()[0];
    }
    }
    返回null;
    }
    IEnumerable数据源可枚举(字符串文件名、字符串选择字符串、类型[]参数类型)
    {
    string connectionString=string.Format(connectionTemplate,GetFullFilename(fileName));
    IDataAdapter=新的OleDbDataAdapter(选择String,connectionString);
    数据集=新数据集();
    列表行=新列表();
    尝试
    {
    adapter.Fill(数据集);
    foreach(数据集中的DataRow行。表[0]。行)
    Add(ConvertParameters(row.ItemArray,parameterTypes));
    }
    最后
    {
    IDisposable一次性=适配器为IDisposable;
    一次性的,一次性的;
    }
    object[]columns=新对象[parameterTypes.Length];
    对于(int i=0;ir[i])。ToList();
    }
    List rv=新列表();
    rv.Add(columns.ToArray());
    返回rv;
    }
    IEnumerable数据源(字符串文件名、字符串selectString、类型[]参数类型)
    {
    string connectionString=string.Format(connectionTemplate,GetFullFilename(fileName));
    IDataAdapter=新的OleDbDataAdapter(选择String,connectionString);
    数据集=新数据集();
    尝试
    {
    adapter.Fill(数据集);
    foreach(数据集中的DataRow行。表[0]。行)
    收益率返回参数(row.ItemArray,parameterTypes);
    }
    最后
    {
    IDisposable一次性=适配器为IDisposable;
    一次性的,一次性的;
    }
    }
    静态字符串GetFullFilename(字符串文件名)
    {
    字符串可执行文件=新Uri(Assembly.getExecutionGassembly().CodeBase).LocalPath;
    返回Path.GetFullPath(Path.Combine(Path.GetDirectoryName(可执行文件),文件名));
    }
    静态对象[]转换参数(对象[]值,类型[]参数类型)
    {
    object[]result=新对象[values.Length];
    for(intidx=0;idx=parameterTypes.Length?null:parameterTypes[idx]);
    返回结果;
    }
    /// 
    ///如有必要,将参数转换为其目标参数类型。
    /// 
    ///参数值
    ///目标参数类型(如果未知,则为null)
    ///转换后的参数值
    静态对象参数(对象参数,类型参数类型)
    {
    if((参数为double | |参数为float)&&
    (parameterType==typeof(int)| | parameterType==typeof(int?))
    {
    int值;
    字符串floatValueAsString=参数.ToString();
    if(Int32.TryParse(floatValueAsString,out intValue))
    返回值;
    }
    返回参数;
    }
    }
    }