Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.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# 如何使用Fluent断言比较两个因属性而异的集合?_C#_Unit Testing_Fluent Assertions - Fatal编程技术网

C# 如何使用Fluent断言比较两个因属性而异的集合?

C# 如何使用Fluent断言比较两个因属性而异的集合?,c#,unit-testing,fluent-assertions,C#,Unit Testing,Fluent Assertions,我有一个公共类RuleInfo,它是从内部类Rule创建的 private static RuleInfo CreateRuleInfo(Rule r) { return new RuleInfo { RuleCode = r.RuleId, DisplayName = r.RuleCode, Description = r.Description, LegacyRuleCode = null }; } 它

我有一个公共类
RuleInfo
,它是从内部类
Rule
创建的

private static RuleInfo CreateRuleInfo(Rule r)
{
    return new RuleInfo
    {
        RuleCode = r.RuleId,
        DisplayName = r.RuleCode,
        Description = r.Description,
        LegacyRuleCode = null
    };
}
它们的属性名称不同,因此
shouldbeeequivalentto()
ShouldBeEquivalentTo()
不起作用

现在我正在手动/显式地比较它们:

foreach (var x in Enumerable.Zip(infs, rules, (i, r) => new { Info = i, Rule = r }))
{
    x.Info.ShouldBeEquivalentTo(
        new
        {
            RuleCode = x.Rule.RuleId,
            DisplayName = x.Rule.RuleCode,
            Description = x.Rule.Description,
            LegacyRuleCode = (string)null
        });
}

是否有更好、更紧凑、更不明确、更可读的方法?

不幸的是,目前没有一种方法可以在比较不同类型时指定属性之间的映射。这件事是公开的

下面是一个关于比较两个集合的另一种方法的示例。 请注意,我假设
==
执行值相等。 因此,如果您的所有属性都是
int
string
,您就安全到家了

ruleInfos.Should().Equal(rules, (ruleInfo, rule) =>
    ruleInfo.RuleCode == rule.RuleId
     && ruleInfo.DisplayName == rule.RuleCode
    && ruleInfo.Description == rule.Description
);
例如,对于没有重载
=
的引用类型,您需要使用例如

(PropertyA == PropertyB) || (PropertyA?.Equals(PropertyB) == true

一个选项是将自定义等效步骤添加到全局选项配置:

class DifferentObjectsEquivalencyStep<T1, T2> : IEquivalencyStep {
    private readonly Func<T1, T2> _converter;

    public DifferentObjectsEquivalencyStep(Func<T1, T2> converter) {
        _converter = converter;
    }

    public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config) {
        return context.Subject is T1 && context.Expectation is T2 || context.Subject is T2 && context.Expectation is T1;
    }

    public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config) {            
        var first = context.Subject is T1 ? (T1) context.Subject : (T1) context.Expectation;
        var second = context.Subject is T2 ? (T2) context.Subject : (T2) context.Expectation;
        second.ShouldBeEquivalentTo(_converter(first));
        return true;
    }
}

谢谢你的回答!我从中更多地了解了faapi。刚发现乔纳斯的答案很短:)
AssertionOptions.AssertEquivalencyUsing(c => c.Using(
            new DifferentObjectsEquivalencyStep<Rule, RuleInfo>(CreateRuleInfo)));
rule.ShouldBeEquivalentTo(info);