通过已定义的具体类型的成员循环?

时间:2016-06-08 16:57:30

标签: c# unit-testing linq-to-sql

我正在跨数据库进行比较(大约有20个字段),并且我已经定义了一个具体的类型来处理比较。

如果我的比较失败,我想循环遍历catch块中的各个项目,并向用户提供列表错误。下面,我通过前几个变量手动完成了它。是否有更有效的方法来循环遍历所有20个字段?我开始使用foreach(Object objectItem ..但不确定这是否是正确的方法。

有任何想法或急需指导吗?

      try { 

        CollectionAssert.IsSubsetOf(orgs, members, "Error Matching testlist Fields");

          }

        catch
        {
            //OrgID
            var sourceOrgID = orgs.Select(o => o.OrgID);
            var destOrgID = members.Select(o => o.OrgID);
            var errorList1 = sourceOrgID.Except(destOrgID);
            string failedTests = null; 
            failedTests = string.Join("\n", errorList1);
            Assert.IsTrue(0 == failedTests.Length, "The following Org IDs are not contained in the source: \n" + failedTests);

            //DealerCode
            var sourceDealerCode = orgs.Select(o => o.DealerCode);
            var destDealerCode = members.Select(o => o.DealerCode);
            var errorList2 = sourceDealerCode.Except(destDealerCode);
            failedTests = null; 
            failedTests = string.Join("\n", errorList2);
            Assert.IsTrue(0 == failedTests.Length, "The following Dealer Codes are not contained in the source: \n" + failedTests);


            //orgkey
            var sourceOrgKey = orgs.Select(o => o.OrgKey);
            var destOrgKey = members.Select(o => o.OrgKey);
            var errorList3 = sourceOrgKey.Except(destOrgKey);
            failedTests = null; 
            failedTests = string.Join("\n", errorList3);
            Assert.IsTrue(0 == failedTests.Length, "The following Org Keys are not contained in the source: \n" + failedTests);

3 个答案:

答案 0 :(得分:0)

你需要反思来做到这一点:

Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();

foreach (PropertyInfo property in properties)
{
    GetColumn(orgList,property.Name); 
}



var names = items.Select(x => x.GetType().GetProperty("prpname").GetValue(x));


public IEnumerable<object> GetColumn(List<Item> items, string columnName)
{
    var values = items.Select(x => 
x.GetType().GetProperty(columnName).GetValue(x));//u can put your test code heere and you can loop it through object properties
}

你可以创建一个列表来存储rslt并将结果添加到列表中,否则你可以在日志文件中写出输出

答案 1 :(得分:0)

如果我没有误解你的问题,你可以使用shouldly做这样的事情

    [TestMethod]
    public void UnitTestExample()
    {
        var orgs = new Organisation
        {
            Ids = new List<int>{ 1,3 },
            DealerCodes = new List<string> { "foo","bar"}
        };

        var members = new Organisation
        {
            Ids = new List<int> { 1,2,3 },
            DealerCodes = new List<string> { "foo", "bar", "buzz" }
        };

        orgs.ShouldSatisfyAllConditions(
            () => orgs.Ids.ShouldBe(members.Ids, ignoreOrder: true),
            () => orgs.DealerCodes.ShouldBe(members.DealerCodes, ignoreOrder: true)
            );
    }

产生的输出是:

enter image description here

你仍然需要在ShouldSatisfyAllConditions中指定你想要检查的每个属性,但是应该在比较列表并输出差异时做所有繁重的工作。

答案 2 :(得分:0)

我认为:

  1. orgsIQueryable<T1>
  2. membersIQueryable<T2>
  3. typeof(T1) == typeof(T2)
  4. 如果是这样,该功能可以提供帮助:

    private static void CompareRecords<TEntity>(IQueryable<TEntity> orgs, IQueryable<TEntity> members)
    {
      var entityType = typeof (TEntity);
      var selectMethod = typeof (Queryable).GetMethods().First(x => x.Name == "Select");
      var exceptMethod = typeof(Queryable).GetMethods().First(x => x.Name == "Except");
      var toArrayMethod = typeof (Enumerable).GetMethods().First(x => x.Name == "ToArray");
    
      foreach (var property in entityType.GetProperties())
      {
        var paramExpr = Expression.Parameter(entityType, "x");
        var propExpr = Expression.Property(paramExpr, property.Name);
        var delegateType = typeof (Func<,>).MakeGenericType(entityType, property.PropertyType);
        var lambdaExpr = Expression.Lambda(delegateType, propExpr, paramExpr);
    
        var parameterizedSelectMethod = selectMethod.MakeGenericMethod(entityType, property.PropertyType);
        var parameterizedExceptMethod = exceptMethod.MakeGenericMethod(property.PropertyType);
    
        var source = parameterizedSelectMethod.Invoke(null, new object[] {orgs, lambdaExpr});
        var dest = parameterizedSelectMethod.Invoke(null, new object[] {members, lambdaExpr});
    
        var errorList = parameterizedExceptMethod.Invoke(null, new[] {source, dest});
    
        var errorListArray = toArrayMethod.MakeGenericMethod(property.PropertyType).Invoke(null, new[] {errorList});
    
        var failedTests = string.Join("\n", ((IEnumerable)errorListArray).Cast<object>().Select(x => x.ToString()));
        Assert.IsTrue(0 == failedTests.Length, $"The following {property.Name} are not contained in the source: \n{failedTests}");
      }
    }