c# - 将枚举与自定义 Fluent Assertions 等效步骤进行比较

标签 c# .net fluent-assertions

我正在尝试为 Fluent Assertions 编写自定义等效步骤,以将主题端的 Enum 值与异常端的字符串进行比较。

我似乎面临的问题是,在调用我的 EquivalencyStep 之前,传递给 IEquivalencyStep 的主题类型已经转换为字符串。

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

代码示例如下:

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);
    }
}

更新:

根据上面的问题,我已经将代码修改为下面的代码,以防其他人遇到同样的问题。

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);
    }
}

最佳答案

这是一个错误。您正在注册我们称为用户等效步骤的东西。但是这些在内置的 TryConversionEquivalencyStep 之后运行ReferenceEqualityEquivalencyStep .如果您可以将此作为错误提交,我们可以查看它。作为解决方法,请考虑使用 AssertionOptions.EquivalencySteps.Insert<ComparingEnumWith<T>>(); 在所有内置步骤之前插入您的自定义步骤。

关于c# - 将枚举与自定义 Fluent Assertions 等效步骤进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35609064/

相关文章:

c# - 表达式.条件 : Argument types do not match

c# - 服务栈服务器事件

c# - 在 C# 和 F# 之间交换大列表

c# - Web 应用程序上下文中 win32 dll 和 .net dll 之间的区别?

c# - 为什么面试官要问高级问题?

c# - FluentAssertions - 如何使 ShouldBeEquivalentTo 比较空和 null 是否相等

c# - ADO.Net 中的异步编程

c++ - 如何在 C++ ATL/MFC 中检索具有与 DateTime.Ticks 相同格式的刻度

c# - FluentAssertions : ShouldBeEquivalentTo vs Should(). Be() vs Should().BeEquivalentTo()?

ShouldBeEquivalentTo 的 C# Fluent Assertions 全局选项