C# 比较枚举与自定义Fluent断言的等价性步骤

C# 比较枚举与自定义Fluent断言的等价性步骤,c#,.net,fluent-assertions,C#,.net,Fluent Assertions,我试图为流畅的断言编写一个自定义等价步骤,将主题端的Enum值与异常端的字符串进行比较 我似乎面临的问题是,传入ieequivalencystep的主题类型在调用我的EquivalencyStep之前已转换为字符串 在尝试将枚举直接转换为字符串的fluent断言中是否发生了一些神奇的事情 代码示例如下所示: public class SubjectClass { public EnumType Prop1 { get; set; } } public enum EnumType {

我试图为流畅的断言编写一个自定义等价步骤,将主题端的
Enum
值与异常端的字符串进行比较

我似乎面临的问题是,传入
ieequivalencystep
的主题类型在调用我的
EquivalencyStep
之前已转换为字符串

在尝试将枚举直接转换为字符串的fluent断言中是否发生了一些神奇的事情

代码示例如下所示:

public class SubjectClass
{
    public EnumType Prop1 { get; set; }
}

public enum EnumType
{
    A,
    B,
    C
}

public class ExpectionClass
{
    public string Prop1 { get; set; }
}

[TestFixture]
public class ComparingEnumWithTests
{
    [Test]
    public void Test()
    {
        var expection = new ExpectionClass() {Prop1 = "bbb"};

        var subject = new SubjectClass() {Prop1 = EnumType.B};

        subject.ShouldBeEquivalentTo(expection, opt => opt.Using(new ComparingEnumWith<EnumType>(new Dictionary<string, EnumType>()
        {
            {"aaa", EnumType.A },
            {"bbb", EnumType.B },
            {"ccc", EnumType.C }
        })));

    }
}

public class ComparingEnumWith<TEnum> : IEquivalencyStep
    where TEnum : struct
{
    private readonly IReadOnlyDictionary<string, TEnum> _dictionary;
    private readonly Type _enumType;

    public ComparingEnumWith(IReadOnlyDictionary<string, TEnum> dictionary)
    {
        _enumType = typeof(TEnum);
        if (!_enumType.IsEnum)
        {
            throw new ArgumentException("TEnum must be an enum");
        }

        _dictionary = dictionary;
    }

    public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
    {
        var subjectType = config.GetSubjectType(context);

        return subjectType != null && subjectType == _enumType && context.Expectation is string;
    }

    public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
    {
        var expected = _dictionary[(string)context.Expectation];

        return ((TEnum)context.Subject).Equals(expected);
    }
}
公共类SubjectClass
{
公共枚举类型Prop1{get;set;}
}
公共枚举类型
{
A.
B
C
}
公共类ExpectionClass
{
公共字符串Prop1{get;set;}
}
[测试夹具]
公共类与测试的比较
{
[测试]
公开无效测试()
{
var expection=new ExpectionClass(){Prop1=“bbb”};
var subject=new SubjectClass(){Prop1=EnumType.B};
subject.ShouldBeEquivalentTo(expection,opt=>opt.Using(newcomparingnumwith(newdictionary)()
{
{“aaa”,枚举类型.A},
{“bbb”,EnumType.B},
{“ccc”,EnumType.C}
})));
}
}
公共类比较:IEEquivalencyStep
其中TEnum:struct
{
私人只读iReadOnly字典;
私有只读类型_enumType;
公共比较词典(iRadonlyDictionary)
{
_enumType=typeof(十微米);
if(!\u enumType.IsEnum)
{
抛出新ArgumentException(“TEnum必须是枚举”);
}
_字典=字典;
}
public bool CanHandle(IEEquivalencyValidationContext,IEEquivalencyAssertionOptions配置)
{
var subjectType=config.GetSubjectType(上下文);
返回subjectType!=null&&subjectType==\u enumType&&context。期望值为字符串;
}
公共bool句柄(IEEquivalencyValidationContext、IEEquivalencyValidator父级、IEEquivalencyAssertionOptions配置)
{
var expected=_dictionary[(string)context.Expectation];
return((TEnum)context.Subject).Equals(预期);
}
}
更新:

根据上面的问题,我将代码修改为下面的代码,以防其他人也有同样的问题

public class SubjectClass
{
    public EnumType Prop1 { get; set; }
}

public enum EnumType
{
    A,
    B,
    C
}

public class ExpectionClass
{
    public string Prop1 { get; set; }
}

[TestFixture]
public class ComparingEnumWithTests
{
    [Test]
    public void Test()
    {
        var expection = new ExpectionClass() {Prop1 = "bbb"};

        var subject = new SubjectClass() {Prop1 = EnumType.B};
        AssertionOptions.EquivalencySteps.Insert<ComparingEnumWith<EnumTypeDataMapProvider, EnumType>>();
        subject.ShouldBeEquivalentTo(expection);

    }
}

public interface IEnumDataMapProvider<TEnum>
{
    IReadOnlyDictionary<string, TEnum> Map { get; }
}

public class EnumTypeDataMapProvider : IEnumDataMapProvider<EnumType>
{
    public IReadOnlyDictionary<string, EnumType> Map => new Dictionary<string, EnumType>()
    {
        {"aaa", EnumType.A},
        {"bbb", EnumType.B},
        {"ccc", EnumType.C}
    };
}


public class ComparingEnumWith<TMapProvider, TEnum> : IEquivalencyStep
    where TMapProvider : IEnumDataMapProvider<TEnum>
    where TEnum : struct
{
    private readonly IReadOnlyDictionary<string, TEnum> _dictionary;
    private readonly Type _enumType;

    public ComparingEnumWith()
    {
        _enumType = typeof(TEnum);
        if (!_enumType.IsEnum)
        {
            throw new ArgumentException("TEnum must be an enum");
        }

        var provider = Activator.CreateInstance<TMapProvider>();

        _dictionary = provider.Map;
    }

    public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
    {
        var subjectType = config.GetSubjectType(context);

        return subjectType != null && subjectType == _enumType && context.Expectation is string;
    }

    public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
    {
        var expected = _dictionary[(string)context.Expectation];

        return ((TEnum)context.Subject).Equals(expected);
    }
}
公共类SubjectClass
{
公共枚举类型Prop1{get;set;}
}
公共枚举类型
{
A.
B
C
}
公共类ExpectionClass
{
公共字符串Prop1{get;set;}
}
[测试夹具]
公共类与测试的比较
{
[测试]
公开无效测试()
{
var expection=new ExpectionClass(){Prop1=“bbb”};
var subject=new SubjectClass(){Prop1=EnumType.B};
AssertionOptions.equalencycysteps.Insert();
受试者。应等同于(预期);
}
}
公共接口IEnumDataMapProvider
{
IReadOnlyDictionary映射{get;}
}
公共类EnumTypeDataMapProvider:IEnumDataMapProvider
{
公共IReadOnlyDictionary映射=>new Dictionary()
{
{“aaa”,枚举类型.A},
{“bbb”,EnumType.B},
{“ccc”,EnumType.C}
};
}
公共类比较:IEEquivalencyStep
其中TMapProvider:IEnumDataMapProvider
其中TEnum:struct
{
私人只读iReadOnly字典;
私有只读类型_enumType;
公共比较
{
_enumType=typeof(十微米);
if(!\u enumType.IsEnum)
{
抛出新ArgumentException(“TEnum必须是枚举”);
}
var provider=Activator.CreateInstance();
_dictionary=provider.Map;
}
public bool CanHandle(IEEquivalencyValidationContext,IEEquivalencyAssertionOptions配置)
{
var subjectType=config.GetSubjectType(上下文);
返回subjectType!=null&&subjectType==\u enumType&&context。期望值为字符串;
}
公共bool句柄(IEEquivalencyValidationContext、IEEquivalencyValidator父级、IEEquivalencyAssertionOptions配置)
{
var expected=_dictionary[(string)context.Expectation];
return((TEnum)context.Subject).Equals(预期);
}
}

这是一个bug。您正在注册我们称之为用户等效步骤的内容。但是它们在内置的
tryconversionequivalencycystep
ReferenceEqualityEquivalencyStep
之后运行。如果你能把它作为bug归档,我们可以看看。作为一种解决方案,考虑在使用“代码>断言选项”的所有内置步骤之前插入自定义步骤。代码>

看起来这已经被修复了,你能确认@Dennis并更新你的答案吗?
Insert
方法将把它放在内置步骤之前。但多年来一直如此。